如何创建带文件孔的文件?

时间:2011-03-15 17:17:27

标签: c linux

文件孔是文件中的空白区域,但是它不占用任何磁盘空间并包含空字节。因此,文件大小大于磁盘上的实际大小。

但是,我不知道如何创建带有文件孔的文件进行试验。

6 个答案:

答案 0 :(得分:33)

使用带有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。其他人回复了a nice alternative method that is very Linux specific。我在这里强调它,因为它是一种与我给出的两种方法不同的方法,可以用来在现有文件中添加漏洞。

答案 1 :(得分:7)

  1. 创建文件。
  2. 寻找N
  3. 写一些数据。
  4. 文件的开头会有一个洞(最多,不包括位置N)。您可以类似地在中间创建带孔的文件。

    以下文档包含一些示例C代码(搜索“稀疏文件”):http://www.win.tue.nl/~aeb/linux/lk/lk-6.html

答案 2 :(得分:6)

除了创建带漏洞的文件之外,从大约2个月前(2011年1月中旬)开始,您可以使用fallocate(2) FALLOC_FL_PUNCH_HOLE LWN article,{{1}} {{1}} git commit on Linus' tree,在Linux上的现有文件上打洞。 {3}},patch to Linux's manpages

答案 3 :(得分:3)

这个问题在W.Richard Stevens着名书籍“UNIX环境中的高级编程”(简称APUE)的第3.6节中进行了详细讨论。这里使用unistd.h中包含的lseek funstion,它用于显式设置打开文件的偏移量。 lseek函数的原型如下:

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

这里,filedes是文件描述符,offset是我们愿意设置的值,并且是在头文件中设置的常量,特别是SEEK_SET,这意味着偏移量是从文件的开头设置的; SEEK_CUR,表示偏移量设置为当前值加上争议列表中的偏移量; SEEK_END,意味着文件的偏移量设置为文件的大小加上争论列表中的偏移量。

在UNIX下像OS一样在C中创建带孔的文件的示例如下:

/*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是处理与系统调用相关的致命错误的函数。

答案 4 :(得分:2)

有关如何创建文件孔的信息,请参阅此手册页:srec_binary。 另请查看文件漏洞上的LWN article

答案 5 :(得分:1)

您可以使用coredump文件。由于内存中包含孔,因此您将拥有一个带孔的文件。