你如何以编程方式在linux上创建一个完全空的稀疏文件?

时间:2015-11-24 21:24:08

标签: c linux sparse-file

如果你用这个运行dd:

<td>{{$user->phone->phone}}</td>

您似乎获得了一个完全未分配的稀疏文件(这是ext4)

dd if=/dev/zero of=sparsefile bs=1 count=0 seek=1048576

fibmap同意:

smark@we:/sp$ ls -ls sparsefile 
0 -rw-rw-r-- 1 smark smark 1048576 Nov 24 16:19 sparsefile

无需深入了解dd的来源,我正试图弄清楚如何在C中做到这一点。

我尝试过fseeking并写入零字节,但它没有做任何事情。 不知道还有什么可以尝试,我想在我追捕dd的内脏之前有人可能知道。

编辑:包括我的例子......

smark@we:/sp$ sudo hdparm --fibmap sparsefile 
sparsefile:
 filesystem blocksize 4096, begins at LBA 2048; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors

2 个答案:

答案 0 :(得分:7)

当您使用write或最终调用write的各种库例程写入文件时,会出现与文件描述符关联的文件偏移量指针文件中的字节将在哪里。它通常位于最近一次调用readwrite处理的数据末尾。但是您可以使用lseek将指针放在文件中的任何位置,甚至超出文件的当前末尾。当您在超出当前EOF的位置写入数据时,跳过的区域在概念上用零填充。许多系统会对事物进行优化,以便不会分配该跳过区域中的任何整个文件系统块,从而产生稀疏文件。尝试读取这些块将成功,返回零。

将一个充满零的块大小的区域写入文件通常不会产生稀疏文件,尽管某些文件系统可以这样做。

生成GNU dd使用的稀疏文件的另一种方法是调用ftruncatedocumentation说明了这一点:

  

ftruncate()函数使fildes引用的常规文件的大小为length个字节。

     

如果之前的文件大于length,则会丢弃额外的数据。如果它先前短于长度,则未指定文件是否已更改或其大小是否增加。 如果文件已扩展,则扩展区域显示为零填充。

对稀疏文件的支持是特定于文件系统的,尽管几乎所有针对UNIX的本地文件系统都支持它们。

答案 1 :(得分:5)

这是@ MarkPlotnick的答案的补充,它是您使用ftruncate()请求的功能的示例简单实现:

#include <unistd.h>
#include <fcntl.h>

#include <sys/stat.h>

int
main(void)
{
    int file;
    int mode;

    mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
    file = open("sparsefile", O_WRONLY | O_CREAT, mode);
    if (file == -1)
        return -1;
    ftruncate(file, 0x100000);
    close(file);

    return 0;
}