linux文件空洞

来源:互联网 发布:贵州移动网络建设 编辑:程序博客网 时间:2024/09/21 08:48

在我们学习linux文件操作的时候会学到lseek这个函数。这个函数的原型是:

#include <unistd.h>off_t lseek(int fd,off_t offset,int whence)

返回值:如果成功,返回新的文件偏移量,如果失败返回-1。

在操作lseek函数的时候,大家都知道它可以将文件的偏移指针移到你需要的位置。你可以指定一个位置的相对位置。如:
当whence为SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节。
当whence为SEEK_CUR,则将该文件的偏移量设置为当前位置加offset个字节,offset可正可负。
当whence为SEEK_END,则将该文件的偏移量设置为文件长度加offset个字节,offset可正可负。
如果执行成功会返回一个新的文件偏移量。

当你文件的偏移量大于原本文件的当前长度,这是允许的,就像上面的红色字体所述。当你这时再向文件执行写操作,写入的数据会凑够你指定的偏移量开始执行。这就引发了文件空洞这个问题。
这是测试:

int main(){int fd=open("./file1",O_WRONLY|O_CREAT,0600);assert(fd != -1);char buff[100];write(fd,"hello world",11);lseek(fd,16680,SEEK_SET);write(fd,"CHINA",6);printf("main over");close(fd);return 0;}

这个是没有执行lseek时文件的相关信息:
这里写图片描述

这是执行lseek后再向文件中写入数据的一个信息。可以看出在中间未写入字节的地方被填充上了\0
这里写图片描述
为了证明文件确实存在空洞,将刚创建的文件与同样长度但无空洞的文件进行比较:
这里写图片描述
虽然两个文件长度相同但是无空洞的文件占用20个磁盘块,而具有空洞的文件只占用8个磁盘块。
如果使用cat复制这个文件,那么所有的空洞会被填满,其中所有实际数据字节皆填写为0.这个原因是,文件系统使用了若干块以存放实际数据块的各个指针。

这里写图片描述
对于没有写过的字节位置,read函数读到的字节是0。如果执行下面的命令,可以看出正常的I/O操作读整个文件长度:
这里写图片描述
关于文件空洞的其他更深入的,未完待续!

0 0
原创粉丝点击