据我了解,我一直在阅读高级的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
答案 0 :(得分:1)
带孔的文件将数据存储在两个独立的磁盘块上。
没有空洞的文件将数据存储在一个磁盘块上。
ls
报告的大小是文件中的字节数,而不是磁盘块中存储的字节数。丢失的字节都是零,因为od -c
的输出清楚。
请注意,使用lseek()
的重点不是在文件中创建漏洞。这些是实现细节。使用lseek()
的原因是将读/写位置放在要读取或写入下一个文件的文件中。例如,在具有固定大小记录的文件中,您可以使用lseek(fd, N * sizeof(struct Record), SEEK_SET)
到达第N条记录,然后在该位置读取(或写入)数据。