您的位置:首页 > 运维架构 > Linux

linux文件空洞

2016-04-12 09:31 771 查看
在我们学习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操作读整个文件长度:



关于文件空洞的其他更深入的,未完待续!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: