linux操作系统中,文件的偏移量可以大于文件的实际长度(用lseek函数设置偏移量),那么在接下来写时会加长extend这个文件,则中间就形成空洞hole,读出时hole里没有操作的空间会显示为null或0。在linux的文件系统下,这个hole是不占用磁盘空间的。
下面做一下演示:
一、创建一个正常文件sparse-file
linux-smtp:/home/test # echo "adbcdef" >sparse-file
linux-smtp:/home/test # ll -sh sparse-file
4.0K -rw-r--r-- 1 root root 8 Apr 4 02:21 sparse-file //占用一个block 4.0k 8个字节
linux-smtp:/home/test # od -c sparse-file //dump file in ASCII mode
0000000 a d b c d e f \n
0000010
linux-smtp:/home/test # du -b sparse-file //使用du工具查看
8 sparse-file
linux-smtp:/home/test # du -h sparse-file
4.0K sparse-file
二、在sparse-file基础上制造文件空洞
linux-smtp:/home/test # dd if=sparse-file of=sparse-file bs=1 count=8 seek=32K //seek参数表示跳过输出 文件开始的32K个block(1个字节/block,本例中)然后写
linux-smtp:/home/test # ll -s sparse-file
8 -rw-r--r-- 1 root root 32776 Apr 4 02:32 sparse-file //占用磁盘空间8K,两个block
linux-smtp:/home/test # ll -sh sparse-file
8.0K -rw-r--r-- 1 root root 33K Apr 4 02:32 sparse-file
linux-smtp:/home/test # od -c sparse-file //od工具查看,hole显示为0
0000000 a d b c d e f \n \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0100000 a d b c d e f \n
0100010
linux-smtp:/home/test # du -h sparse-file
8.0K sparse-file
linux-smtp:/home/test # du -b sparse-file
32776 sparse-file
显示文件大小是把空洞的空间计算在内的。
另外,文件空洞跟写0,还是不一样的,如果中间写0,系统还是会实实在在地给文件分配磁盘空间的
linux-smtp:/home/test # dd if=/dev/zero of=sparse-file bs=1 count=32K seek=8
linux-smtp:/home/test # od -c sparse-file
0000000 a d b c d e f \n \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0100000 \0 \0 \0 \0 \0 \0 \0 \0
0100010
linux-smtp:/home/test # ll -sh sparse-file
36K -rw-r--r-- 1 root root 33K Apr 4 02:51 sparse-file
linux-smtp:/home/test # echo "adbcdef" >>sparse-file
linux-smtp:/home/test # od -c sparse-file
0000000 a d b c d e f \n \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0100000 \0 \0 \0 \0 \0 \0 \0 \0 a d b c d e f \n
0100020
linux-smtp:/home/test # du -h sparse-file
36K sparse-file