空洞文件,制作空洞文件,truncate、ftrucate制作,lseek制作【linux】(s)

空洞文件

在一般文件的情况下,对于普通文件来说,文件数据的理论大小 == 在块设备上实际占用的空间大小。
但是空洞文件却不是这样的,对于空洞文件来说,

文件数据的理论大小 > 在块设备上实际占用的空间大小。

空洞文件的意义

打个比方

我承诺给你一亩地,但是你又不是马上就要用满这一亩地,是一点一点来占用的,如果我现在一下子就把一亩地全部给你,但是你要花费很久时间才会把地全用上,在你占满之前,一直有相当部分的空间被闲置不用,显然非常浪费空间资源。

解决办法是,我先承诺说给你一亩地,但是这一亩地先不全部给你,你搬一部分东西过来时,我给你一部分空间,按照这样的方式,直到把1亩地的空间全部给你,在你没有用满一亩地之前,其它的空间我就可以用作其他用处。

迅雷等下载文件

比如下载一个1M大小的文件,文件肯定是要花费相当长的时间才能下载完成,如果我直接就开辟一个实际占用1M空间的普通文件来放数据的话,在实际下载完数据之前,未装满数据的空间都被闲置,会很浪费空间。

解决办法就是开辟一个1M大小的空洞文件,空洞文件的理论大小是1M,但是并没有在块设备上实际给你分配1M的物理空间,
而是在下载过程中,每下载一部分数据,再实际开辟一部分空间给你,直到整个文件下完位置。

制作空洞文件

truncate、ftrucate制作

文件截短长度 > 文件长度时,多余的部分就是空洞。

代码演示:
我们先创建一个文件:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
        int fd = 0;
        fd = open("hole_file.txt",O_RDWR|O_CREAT,0777);
        if(-1 == fd)
        {
                printf("open fail\n");
                exit(-1);
        }
        return 0;
}

执行结果为:
在这里插入图片描述在这里插入图片描述

我们可以看到创建成功大小为0。

我们现在进行截断,把问hole_file.txt文件大小设置为8000:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
        int fd = 0;
        fd = open("hole_file.txt",O_RDWR|O_CREAT,0777);
        if(-1 == fd)
        {
                printf("open fail\n");
                exit(-1);
        }

        ftruncate(fd,8000);
        return 0;
}

执行结果为:
在这里插入图片描述我们可以看到现在文件的理论大小已经修改为8000

我们查看以下命令查看实际的文件在块设备上占用的大小:
du命令:查看文件在块设备上,实际占用的物理空间。

在这里插入图片描述我们可以看到实际在磁盘上所占用的空间大小为0

ls查看到的只是文件的理论大小,但是空洞部分并不占用实际物理存储空间。我们打开查看一下空洞文件:
在这里插入图片描述
这种表示是空洞文件。
我们用二进制查看里面都是0
在这里插入图片描述

lseek制作

将文件读写位置调整到文件尾部之后,然后写点数据,中间空出的部分就是空洞。

代码演示:
我们先把刚才的hole_file.txt 文件删除了

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
        int fd = 0;
        fd = open("hole_file.txt",O_RDWR|O_CREAT,0777);
        if(-1 == fd)
        {
                printf("open fail\n");
                exit(-1);
        }
        lseek(fd,8000,SEEK_SET);
        write(fd,"hello",5);
        return 0;
}

执行结果为:
在这里插入图片描述
我们可以看到文件理论大小为8005

实际大小为:
在这里插入图片描述这里的4表示4k 就是4096个字节,是用来存放hello的,空洞部分不占用实际空间,块设备在分配空间的时候,如果根据需要的字节来分配的话效率不高,所以按照块来存储,效率比较高,最开始也会分配4块,这4块存储的就是hello,当把4块存储满了之后再单独开辟块进行存储。所以空洞部分还是没有占用实际的存储空间。

发布了85 篇原创文章 · 获赞 71 · 访问量 9222

猜你喜欢

转载自blog.csdn.net/qq_43648751/article/details/104246740