据我所知,我一直在阅读高级 unix 编程书籍。对文件使用 lseek 并创建一个洞应该使用更少的磁盘空间,因为该洞没有记录在磁盘上并且该洞用零填充。
但是我创建了两个文件,一个有孔,一个没有,但是没有孔的文件比有孔的文件占用更少的磁盘空间。我想我可能搞砸了代码,但我不确定我是如何得到这些结果的。因为这似乎与我对文件漏洞的理解相矛盾。这两个文件不应该大小相同吗?
我可能从根本上完全忽略了 lseek 的使用要点?如果是这样,请随意投反对票,因为我知道只允许最高质量的帖子。并解释我在这里缺少什么?谢谢。
使用 lseek 编写代码
#include "apue.h"
#include <fcntl.h>
char buf1[] = "abcdefghik";
char buf2[] = "ABCDEFGHIJ";
int main (void)
{
int fd;
if((fd = creat("file.hole" , FILE_MODE)) < 0)
err_sys("creat error");
if(write(fd , buf1 , 10) != 10)
err_sys("buf1 write error");
//offset now = 10 becaues we wrote 10 bytes
if(lseek(fd , 16384 , SEEK_SET) == -1)
err_sys("lseek error");
/*offset now = 16384 there is now a hole*/
if(write(fd , buf2 , 10) != 10)
err_sys("buf2 write error");
/*offset now 16384 + 10 bytes = 16394*/
exit(0);
//now have a gap in file, however this gap is not written to the disk. so doesn't take up all that space on the disk
}
没有 lseek 的代码
#include "apue.h"
#include <fcntl.h>
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
int main (void){
int fd;
//creating new file
if((fd = creat("file.nohole" , FILE_MODE)) < 0)
err_sys("create error");
//writing 10 bytes of buf1
if(write(fd,buf1,10) != 10)
err_sys("write buf1 error");
//writing 10 bytes of buf2
if(write(fd,buf2,10) != 10)
err_sys("write buf2 error");
exit(0);
//no hole in the file.
}
od -c file.hole(检查内容)
0000000 a b c d e f g h i k \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0040000 A B C D E F G H I J
0040012
od -c file.nohole(检查内容)
0000000 a b c d e f g h i j A B C D E F
0000020 G H I J
0000024
比较两个文件 - ls -ls file.hole file.nohole
28 -rw-r--r-- 1 sam sam 16394 Jul 10 14:09 file.hole
12 -rw-r--r-- 1 sam sam 20 Jul 10 14:32 file.nohole
最佳答案
有洞的文件将数据存储在两个单独的磁盘 block 上。
没有空洞的文件,数据存储在一个磁盘 block 上。
ls
报告的大小是文件中的字节数,而不是存储在磁盘 block 中的字节数。丢失的字节全为零,od -c
的输出清楚地表明了这一点。
请注意,使用 lseek()
的目的不是在文件中创建漏洞。这些是实现细节。使用lseek()
的原因是将文件中的读/写位置放在下一个要读取或写入的位置。例如,在一个固定大小记录的文件中,可以使用lseek(fd, N * sizeof(struct Record), SEEK_SET)
找到第N条记录,然后读取(或写入)数据在那个位置。
关于c - lseek 稀疏文件与常规文件的比较导致意外结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45013933/