C lseek稀疏文件与常规文件的比较是否会导致意外结果?

C lseek稀疏文件与常规文件的比较是否会导致意外结果?,c,unix,C,Unix,据我所知,我一直在阅读高级unix编程书籍。将lseek与文件一起使用并创建一个孔应使用更少的磁盘空间,因为该孔未记录在磁盘上,且孔中填充了零 但是我创建了两个文件,一个有孔,一个没有,但是没有孔的文件比有孔的文件占用更少的磁盘空间。我想我可能把代码搞砸了,但是我不确定我是如何得到这些结果的。因为这似乎与我对文件孔的理解相矛盾。两个文件的大小不应该相同吗 我可能从根本上完全忽略了使用lseek的要点?如果是的话,请随意否决投票,因为我知道只有最高质量的帖子才被允许。解释一下我遗漏了什么?谢谢 使

据我所知,我一直在阅读高级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
}
#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.nohole(检查内容)

比较两个文件-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

带有孔的文件的数据存储在两个单独的磁盘块上

无孔文件的数据存储在一个磁盘块上

ls报告的大小是文件中的字节数,而不是存储在磁盘块中的字节数。从
od-c
的输出可以清楚地看出,缺少的字节都是零


请注意,使用
lseek()
的目的不是在文件中创建孔。这些是实现细节。使用
lseek()
的原因是将读/写位置放在下一个要读取或写入的文件中。例如,在具有固定大小记录的文件中,您可以使用
lseek(fd,N*sizeof(struct record),SEEK\u SET)
到达第N条记录,然后读取(或写入)该位置的数据。

即使您“从根本上忽略了lseek的使用要点”,也没有理由否决这个问题。这个问题被问得很好,格式很好,可以理解,而且有一个很好的解释。(但是我也没有答案)。或者使用
du file*
来获取实际磁盘使用情况。请记住:稀疏文件是一种文件系统功能(或者至少可以是),当使用不支持稀疏文件的lseek代码时,文件系统驱动程序必须创建一个大小为0字节的文件(即vfat)。
0000000   a   b   c   d   e   f   g   h   i   j   A   B   C   D   E   F
0000020   G   H   I   J
0000024
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