文件空洞是文件中的空白区域,它不占用任何磁盘空间且包含 null 字节。因此,文件大小会比实际磁盘上的大小要大。
但我不知道如何创建带有文件空洞的文件以进行实验。
文件空洞是文件中的空白区域,它不占用任何磁盘空间且包含 null 字节。因此,文件大小会比实际磁盘上的大小要大。
但我不知道如何创建带有文件空洞的文件以进行实验。
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的很好的替代方法。我在这里强调一下,因为它是与我提供的两种方法不同的方法,并且可以用于在现有文件中放置空洞。
N
。文件开头(直到排除位置N
)将会有一个空洞。类似地,您可以创建中间带有空洞的文件。
以下文档包含一些示例C代码(搜索“Sparse files”):http://www.win.tue.nl/~aeb/linux/lk/lk-6.html
ftruncate(fileno(outfile), ftell(outfile));
替换,即在执行 fseek
后截断文件至其当前大小。这将允许文件末尾稀疏。 - Martin Scharrer除了创建带有空洞的文件外,自从大约2个月前(2011年1月中旬)起,您可以在Linux上对现有文件打孔,使用fallocate(2)
FALLOC_FL_PUNCH_HOLE
LWN文章,Linus树上的git提交,Linux手册页的补丁。
该问题在W.Richard Stevens的著名书籍《UNIX环境高级编程》(简称APUE)的第3.6节中进行了详细讨论。此处使用unistd.h中包含的lseek函数,该函数旨在显式设置已打开文件的偏移量。 lseek函数的原型如下:
off_t lseek(int filedes, off_t offset, int whence);
这里,filedes是文件描述符,offset是我们想要设置的值,whence是在头文件中设置的常量,具体来说是SEEK_SET,意味着偏移量从文件开头开始设置;SEEK_CUR,意味着偏移量设置为当前值加上参数列表中的偏移量;SEEK_END,意味着文件的偏移量设置为文件大小加上参数列表中的偏移量。
在类UNIX操作系统下创建带有空洞的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;
}