Как создать файл с дырками? - PullRequest
19 голосов
/ 15 марта 2011

Файловые дыры - это пустые места в файле, которые, однако, не занимают места на диске и содержат нулевые байты. Следовательно, размер файла превышает его фактический размер на диске.

Однако я не знаю, как создать файл с дырками для экспериментов.

Ответы [ 6 ]

33 голосов
/ 15 марта 2011

Используйте команду dd с параметром 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

Это создаст для вас файл с хорошей дырой от байта 8192 до байта 28671.

Вотпример, демонстрирующий, что файл действительно содержит дыры (команда ls -s сообщает, сколько блоков диска используется файлом):

$ 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

Как видите, файл с дырами занимаетдо меньшего количества дисковых блоков, несмотря на то, что они имеют одинаковый размер.

Если вам нужна программа, которая делает это, вот она:

#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;
}

Вышеуказанное должно работать на любом Unix.Кто-то еще ответил хорошим альтернативным методом, который очень специфичен для Linux .Я выделю его здесь, потому что это метод, отличный от двух, которые я дал, и его можно использовать для пробелов в существующих файлах.

7 голосов
/ 15 марта 2011
  1. Создание файла.
  2. Поиск в позиции N.
  3. Запись некоторых данных.

В начале будет отверстиефайла (до и без позиции N).Аналогичным образом можно создавать файлы с отверстиями посередине.

В следующем документе приведен пример кода C (поиск по «Разреженным файлам»): http://www.win.tue.nl/~aeb/linux/lk/lk-6.html

6 голосов
/ 15 марта 2011

Помимо создания файлов с дырами, поскольку ~ 2 месяца назад (середина января 2011 года), вы можете пробивать дыры в существующих файлах в Linux, используя fallocate(2) FALLOC_FL_PUNCH_HOLE LWN article , git commit для дерева Линуса , патч для man-страниц Linux .

3 голосов
/ 24 октября 2013

Проблема тщательно обсуждается в разделе 3.6 известной книги У. Ричарда Стивенса "Расширенное программирование в среде UNIX" (APUE для краткости). Здесь используется функция lseek, включенная в unistd.h, которая предназначена для явной установки смещения открытого файла. Прототип функции lseek выглядит следующим образом:

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

Здесь filedes - это дескриптор файла, offset - это значение, которое мы хотим установить, а откуда - постоянная установка в заголовочном файле, в частности, SEEK_SET, что означает, что смещение устанавливается с начала файла; SEEK_CUR, означающий, что смещение установлено в его текущее значение плюс смещение в списке аргументов; SEEK_END, означающий, что смещение файла задает размер файла плюс смещение в списке аргументов.

Пример создания файла с дырами в C под UNIX-подобными ОС выглядит следующим образом:

/*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;
}

В приведенном выше коде err_sys - это функция для решения фатальной ошибки, связанной с системным вызовом.

2 голосов
/ 15 марта 2011

См. Эту справочную страницу для получения информации о том, как создаются файловые дыры: srec_binary .Также взгляните на эту статью LWN о дырах в файлах.

1 голос
/ 09 августа 2015

Вы можете взять файл coredump. Поскольку память содержит дыры, у вас будет файл с дырами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...