gpt4 book ai didi

c - lseek 稀疏文件与常规文件的比较导致意外结果?

转载 作者:太空宇宙 更新时间:2023-11-04 03:21:49 26 4
gpt4 key购买 nike

据我所知,我一直在阅读高级 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com