taller programas notas internos estilos ejercicios ejemplos ejemplo con cabeceras cabecera bloc basico c linux

c - programas - html estilos internos



¿Cómo crear un archivo con agujeros de archivo? (6)

Los orificios de los archivos son los espacios vacíos en el archivo, que, sin embargo, no ocupa ningún espacio en el disco y contiene bytes nulos. Por lo tanto, el tamaño del archivo es mayor que su tamaño real en el disco.

Sin embargo, no sé cómo crear un archivo con agujeros de archivo para experimentar.


  1. Crea un archivo.
  2. Busca posicionar a N
  3. Escribe algunos datos.

Habrá un agujero al inicio del archivo (hasta y excluyendo, posición N ). De manera similar, puede crear archivos con agujeros en el medio.

El siguiente documento tiene algunos ejemplos de código C (busque "Archivos dispersos"): http://www.win.tue.nl/~aeb/linux/lk/lk-6.html



Consulte esta página de manual para obtener información sobre cómo se crean los agujeros de archivo: srec_binary . También eche un vistazo a este artículo de LWN sobre los orificios de los archivos.


El problema se discute cuidadosamente en la sección 3.6 del famoso libro de W.Richard Stevens "Programación avanzada en el entorno UNIX" (APUE para abreviar). El lseek funstion incluido en unistd.h se usa aquí, que está diseñado para establecer explícitamente el desplazamiento de un archivo abierto. El prototipo de la función lseek es el siguiente:

off_t lseek(int filedes, off_t offset, int whence);

Aquí, filedes es el descriptor de archivo, offset es el valor que estamos dispuestos a establecer, y de donde se establece una constante en el archivo de encabezado, específicamente SEEK_SET, lo que significa que la compensación se establece desde el principio del archivo; SEEK_CUR, lo que significa que el desplazamiento se establece en su valor actual más el desplazamiento en la lista de argumentos; SEEK_END, lo que significa que la compensación del archivo se establece en el tamaño del archivo más la compensación en la lista de argumentos.

El ejemplo para crear un archivo con agujeros en C bajo UNIX como sistemas operativos es el siguiente:

/*Creating a file with a hole of size 810*/ #include <fcntl.h> /*Two strings to write to the file*/ char buf1[] = "abcde"; char buf2[] = "ABCDE"; int main() { int fd; /*file descriptor*/ if((fd = creat("file_with_hole", FILE_MODE)) < 0) err_sys("creat error"); if(write(fd, buf1, 5) != 5) err_sys("buf1 write error"); /*offset now 5*/ if(lseek(fd, 815, SEEK_SET) == -1) err_sys("lseek error"); /*offset now 815*/ if(write(fd, buf2, 5) !=5) err_sys("buf2 write error"); /*offset now 820*/ return 0; }

En el código anterior, err_sys es la función para lidiar con un error fatal relacionado con una llamada al sistema.


Puedes tomar un archivo coredump. Como la memoria contiene agujeros, tendrás un archivo con agujeros.


Utilice el comando dd con un parámetro de seek .

dd if=/dev/urandom bs=4096 count=2 of=file_with_holes dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes

Eso crea para usted un archivo con un bonito agujero desde el byte 8192 al byte 28671.

Aquí hay un ejemplo que demuestra que, de hecho, el archivo tiene orificios (el ls -s le dice cuántos bloques de disco está utilizando un archivo):

$ dd if=/dev/urandom bs=4096 count=2 of=fwh # fwh = file with holes 2+0 records in 2+0 records out 8192 bytes (8.2 kB) copied, 0.00195565 s, 4.2 MB/s $ dd if=/dev/urandom seek=7 bs=4096 count=2 of=fwh 2+0 records in 2+0 records out 8192 bytes (8.2 kB) copied, 0.00152742 s, 5.4 MB/s $ dd if=/dev/zero bs=4096 count=9 of=fwnh # fwnh = file with no holes 9+0 records in 9+0 records out 36864 bytes (37 kB) copied, 0.000510568 s, 72.2 MB/s $ ls -ls fw* 16 -rw-rw-r-- 1 hopper hopper 36864 Mar 15 10:25 fwh 36 -rw-rw-r-- 1 hopper hopper 36864 Mar 15 10:29 fwnh

Como puede ver, el archivo con agujeros ocupa menos bloques de disco, a pesar de ser del mismo tamaño.

Si quieres un programa que lo haga, aquí está:

#include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> int main(int argc, const char *argv[]) { char random_garbage[8192]; /* Don''t even bother to initialize */ int fd = -1; if (argc < 2) { fprintf(stderr, "Usage: %s <filename>/n", argv[0]); return 1; } fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) { perror("Can''t open file: "); return 2; } write(fd, random_garbage, 8192); lseek(fd, 5 * 4096, SEEK_CUR); write(fd, random_garbage, 8192); close(fd); return 0; }

Lo anterior debería funcionar en cualquier Unix. Alguien más respondió con un buen método alternativo que es muy específico de Linux . Lo resalté aquí porque es un método distinto de los dos que proporcioné y se puede usar para hacer agujeros en los archivos existentes.