如果你用这个运行dd:
dd if=/dev/zero of=sparsefile bs=1 count=0 seek=1048576
您似乎获得了一个完全未分配的稀疏文件(这是ext4)
smark@we:/sp$ls -ls sparsefile 0 -rw-rw-r-- 1 smark smark 1048576 Nov 24 16:19 sparsefile
fibmap同意:
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
无需深入了解dd的来源,我正试图弄清楚如何在C中做到这一点.
我试过fseeking和写零字节,但它没有做任何事情.
不知道还有什么可以尝试,我想在我追捕dd的内脏之前有人可能知道.
编辑:包括我的例子……
FILE *f = fopen("/sp/sparse2","wb"); fseek(f,1048576,SEEK_CUR); fwrite("x",1,f); fclose(f);
解决方法
当您使用最终调用write的write或各种库例程写入文件时,会有一个与文件描述符关联的文件偏移指针,用于确定文件在文件中的位置.它通常位于最近一次读取或写入调用处理的数据末尾.但是您可以使用
lseek
将指针放在文件中的任何位置,甚至超出文件的当前末尾.当您在超出当前EOF的位置写入数据时,跳过的区域在概念上用零填充.许多系统会对事物进行优化,以便不会分配该跳过区域中的任何整个文件系统块,从而产生稀疏文件.尝试读取这些块将成功,返回零.
将块大小的区域写入文件通常不会产生稀疏文件,尽管某些文件系统可能会这样做.
生成GNU dd使用的稀疏文件的另一种方法是调用ftruncate. documentation说:
The ftruncate() function causes the regular file referenced by fildes to have a size of length bytes.
If the file prevIoUsly was larger than length,the extra data is discarded. If it was prevIoUsly shorter than length,it is unspecified whether the file is changed or its size increased. If the file is extended,the extended area appears as if it were zero-filled.