千家信息网

Linux中sparse文件处理与传输的方法是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"Linux中sparse文件处理与传输的方法是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Linux中sparse文件处理与传输的
千家信息网最后更新 2026年11月02日Linux中sparse文件处理与传输的方法是什么

本篇内容主要讲解"Linux中sparse文件处理与传输的方法是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Linux中sparse文件处理与传输的方法是什么"吧!

0. 什么是sparse文件

当用户申请一块很大的存储空间时,由于最开始并没有写入数据(全是空),此时文件系统为了节省存储资源,提高资源利用率,不会分配实际存储空间,只有当真正写入数据时,操作系统才真正一点一点地分配空间,比如一次64KB。于是这个文件看起来很大,而占用空间很小,实际占用空间只与用户填的数据量有关。该文件看起来像一个大盒子,但可能装的东西不多,空洞很大,因此称为稀疏文件(Sparse file)。Sparse文件是Linux文件系统的一个高级特性,能够实现磁盘的超负载使用(overload)。它最经典的应用就是为虚拟机创建虚拟硬盘以及数据库快照,比如我们使用qemu-img创建一个大小为20GB的raw文件(注意qcow2格式不是sparse文件):

fgp@node1:~$ qemu-img create -f raw test.raw 20G Formatting 'test.raw', fmt=raw size=21474836480 fgp@node1:~$ qemu-img info test.raw image: test.raw file format: raw virtual size: 20G (21474836480 bytes) disk size: 0

以上我们使用qemu-img创建了一个20G的镜像文件,由qemu-img info显示,virtual size为我们分配的空间大小,而disk size为实际占用的空间,最开始并不占任何磁盘空间。

注:qemu-img create -f raw相当于`truncate -s 20G test.raw’。

当然也会有问题,比如系统生成了一堆sparse文件,如果文件系统满了,则这些文件都会写入失败,为了避免这种情况,需要控制sparse文件的数量。

1.如何判断是否sparse文件

除了以上的镜像文件可能是sparse文件,其他文件类型也有可能是sparse文件,如何判断是否sparse文件呢?最简单的办法是使用ls命令和du命令分别查看大小,如果二者大小不一致,则说明是sparse文件。我们可以使用dd命令快速生成一个sparse文件:

dd if=/dev/zero of=sparse_file bs=1M seek=1024 count=0

以上命令从第1024 * 1M处开始写文件(相当于中间空了1GB空间),写入/dev/zero,实际写入了0个块(count=0),因此实际上并没有写入任何数据。我们使用ls -lh查看其大小:

~$ ls -lh sparse_file -rw-rw-r-- 1 fgp fgp 1.0G May 26 15:47 sparse_file

可见该文件显示为1G。

我们再使用du -h命令查看其占用磁盘空间大小:

~$ du -h sparse_file 0   sparse_file

我们发现实际占用磁盘空间为0。

我们也可以直接使用ls的-s参数查看文件实际占用空间大小:

~$ ls -slh sparse_file 0 -rw-rw-r-- 1 fgp fgp 1.0G May 26 15:47 sparse_file

其中***列为实际占用磁盘空间大小,第6列为文件大小(虚拟大小)。

另外使用truncate命令可以随意调节文件大小(如果该文件不存在则会自动创建),比如:

~$ truncate --size 1T sparse_file ~$ du -h sparse_file 0   sparse_file ~$ ls -lh sparse_file -rw-rw-r-- 1 fgp fgp 1.0T May 26 16:09 sparse_file

以上我们把sparse_file文件大小调为1TB,实际上就是往后面追加空洞(extended part (hole) reads as zero bytes),因此不会占用实际磁盘空间。当然也可以缩小文件大小,但是如果比文件数据占用空间还小的话,就会截取数据,因此部分数据会丢失。

truncate -s 500M sparse_file ~$ ls -lh sparse_file -rw-rw-r-- 1 fgp fgp 500M May 26 16:12 sparse_file

以上我们把该文件缩减为500MB。

2. sparse文件处理

sparse文件在处理时也存在一些问题,比如我们使用sed对一个sparse文件进行处理。

fgp@node1:~/tmp$ echo "Hello World" >test.raw fgp@node1:~/tmp$ truncate -s 1G test.raw fgp@node1:~/tmp$ ls -slh total 68K 4.0K -rw-rw-r-- 1 fgp fgp 1.0G May 28 14:52 test.raw fgp@node1:~/tmp$ sed -i 's/Hello/HELLO/g' test.raw fgp@node1:~/tmp$ ls -slh total 1.1G 1.1G -rw-rw-r-- 1 fgp fgp 1.0G May 28 14:53 test.raw

以上我们使用truncate创建了一个sparse文件,然后通过sed命令把Hello改为HELLO,我们期望能够保留该文件的sparse特性,但实际上我们发现仅仅修改了该文件的一行数据,该文件的空洞被填满,瞬间占用磁盘空间为1G。一个只有4K大小的文件使用sed命令后变成了1G,这让人感到莫名其妙不是吗?

再比如我们我们使用tar命令对文件进行归档:

fgp@node1:~/tmp$ qemu-img create -f raw test.raw 1G Formatting 'test.raw', fmt=raw size=1073741824 fgp@node1:~/tmp$ time tar -cf test.tar test.raw  real    0m2.145s user    0m0.012s sys 0m1.640s fgp@node1:~/tmp$ time tar -cJf test.tar.xz test.raw  real    1m0.692s user    0m59.060s sys 0m1.048s fgp@node1:~/tmp$ ls -lsh total 1.1G    0 -rw-r--r-- 1 fgp fgp 1.0G May 28 15:37 test.raw 1.1G -rw-rw-r-- 1 fgp fgp 1.1G May 28 15:37 test.tar 156K -rw-rw-r-- 1 fgp fgp 153K May 28 15:39 test.tar.xz

以上我们创建了一个1G的sparse文件,当使用tar直接归档时发现该文件变成了非sparse文件,占用了1G的磁盘空间。而使用xz压缩时,虽然解决了存储空间的问题,同时也带来压缩时间开销问题(耗费了1分钟的时间进行压缩)。

接下来介绍下熟悉的经典命令cp,cp命令可谓无人不知。众所周知,它用于在本地拷贝文件。值得庆幸(为什么庆幸,因为并不是所有的命令都支持该特性)的是cp命令能够自动探测文件是否sparse文件,空洞数据不会拷贝,并且能够保留sparce文件副本的稀疏性质:

fgp@node1:~$ cp sparse_file sparse_file.copy fgp@node1:~$ ls -slh sparse_file* 0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file 0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file.copy

我们看看和cp命令类似的命令scp,scp用于远程拷贝文件(远程传输文件):

fgp@node1:~$ scp sparse_file localhost:~/sparse_file.copy sparse_file                                            100% 2048MB  97.5MB/s   00:21 fgp@node1:~$ ls -slh sparse_file*    0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file 2.1G -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:42 sparse_file.copy

我们发现scp不能识别sparse文件,传输一个sparse文件时会自动填满空洞,发送整个文件内容。

其实cp命令有一个针对sparse文件拷贝优化的参数--sparse=WHEN,其中WHEN的合法值为auto、always、never,默认为auto,能自动识别是否sparse文件。如果设置为never则会自动填满数据,拷贝整个文件:

fgp@node1:~$ cp --sparse=never sparse_file sparse_file.copy.2 fgp@node1:~$ ls -lhs sparse_file*    0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file 2.1G -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:42 sparse_file.copy 2.1G -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:50 sparse_file.copy.2

可见sparse_file.copy.2填满了空洞,相当于把sparse文件转化成了非sparse文件。

如果指定为always,则cp会尝试把文件转换为sparse文件,减少磁盘占用空间:

fgp@node1:~$ cp --sparse=always sparse_file.copy sparse_file.copy.3 fgp@node1:~$ ls -lsh sparse_file*    0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file 2.1G -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:42 sparse_file.copy 2.1G -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:50 sparse_file.copy.2    0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:52 sparse_file.copy.3

由结果发现,我们把非sparse文件sparse_file.copy转成了sparse文件sparse_file.copy.3。

注:cp命令黑科技,cp实现sparse文件的相互转换!

其实除了cp命令,我们上面的tar命令也支持–sparse参数:

fgp@node1:~/tmp$ time tar -cSf test.tar test.raw  real    0m0.002s user    0m0.000s sys 0m0.000s fgp@node1:~/tmp$ time tar -cSJf test.tar.xz test.raw  real    0m0.011s user    0m0.000s sys 0m0.008s fgp@node1:~/tmp$ ls -slh total 16K    0 -rw-r--r-- 1 fgp fgp 1.0G May 28 15:37 test.raw  12K -rw-rw-r-- 1 fgp fgp  10K May 28 15:42 test.tar 4.0K -rw-rw-r-- 1 fgp fgp  184 May 28 15:43 test.tar.xz

对比前面的结果,我们发现使用tar的-S(–sparse)参数很好的处理sparse文件。

另外cpio也支持同样的参数,但可惜的是scp命令不支持,因此我们使用scp远程传输大量的sparse文件时效率极低,并且浪费大量网络空间。比如我们经常使用qemu-img创建了一个40GB的raw文件,然后需要拷贝镜像到其他机器上,虽然该文件可能只占了1GB左右的磁盘空间,可使用scp需要传输40GB的空间,并且远程需要预留40GB的磁盘空间。那有没有高效传输sparse文件的方法呢?实际上,很可惜,好像并没有,不过有比较好的方法,请看下一节内容。

3.相对高效传输sparse文件的方法

我们前面说了scp不支持sparse文件的处理,好在rsync命令支持sparse文件处理:

fgp@node1:~$ rsync  -av --sparse --progress sparse_file localhost:~/sparse_file.copy fgp@localhost's password: sending incremental file list sparse_file   2,147,483,648 100%   74.67MB/s    0:00:27 (xfr#1, to-chk=0/1)  sent 2,148,008,037 bytes  received 35 bytes  66,092,556.06 bytes/sec total size is 2,147,483,648  speedup is 1.00 fgp@node1:~$ ls -lhs sparse_file* 0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file 0 -rw-rw-r-- 1 fgp fgp 2.0G May 26 16:39 sparse_file.copy

遗憾的是,虽然目标文件保留了其sparse特性,节省了目标主机的存储空间,但并没有节省网络传输带宽,依然传输了2GB的数据,rsync不能过滤掉空洞数据的传输。

值得一提的是rsync有一个参数--inplace,这个参数能够探测源文件和目标文件是否修改的块,传输时只传递修改的块,当然***次传输文件时,这个参数并没有什么用。但可惜的是–sparse参数和–inplace参数不能同时使用。通常做法是***次传输文件时,使用–sparse参数,之后如果对文件进行了修改,需要同步远程时,使用–inplace参数,它只会在原文件的基础上传输更新的块。(可以先在远程目标机器上先使用truncate命令创建一个同名的sparse文件,再使用–inplace参数传递)。

当然如果我们传输的是镜像文件,可以通过qemu-img把raw格式在本地转化为qcow2格式后再传输:

fgp@node1:~/tmp$ ls -lsh total 0 0 -rw-rw-r-- 1 fgp fgp 10G May 28 15:00 test.raw fgp@node1:~/tmp$ qemu-img convert -f raw -O qcow2 test.raw test.qcow2 fgp@node1:~/tmp$ ls -lsh total 196K 196K -rw-r--r-- 1 fgp fgp 193K May 28 15:12 test.qcow2    0 -rw-rw-r-- 1 fgp fgp  10G May 28 15:00 test.raw

转化成qcow2格式后,不再是sparse文件,因此不会存在以上问题。由以上输出我们发现,该文件只有196K,因此传输量大幅度减少。

到此,相信大家对"Linux中sparse文件处理与传输的方法是什么"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

文件 空间 命令 传输 大小 参数 实际 数据 磁盘 处理 方法 空洞 拷贝 支持 系统 问题 存储 内容 实际上 格式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 亿人帮互联网科技有限公司 互联网科技工作委员会主任 科技企业和互联网企业 万易互联网科技 奇酷互联网络科技公司 亿人帮互联网科技 多迪互联网科技有限公司 阿里巴巴算科技企业还是互联网 移动互联网科技股 互联网公司科技股 互联网科技公司有风险吗 注册互联网科技公司经营范围大全 健康食品互联网创新科技园项目 工业互联网等科技实现智能化赋能 张召忠谈中国互联网科技 上海互联网科技公司ppt 福建互联网展示科技馆设计 上海万顺科技互联网有限公司招聘 互联网金融金融科技 数字科技和互联网金融哪个好 互联网科技名片 互联网科技公司排名 深圳互联网科技公司 未来的互联网科技 科技互联网创业计划书 新华互联网科技2019 成都互联网科技公司工作好不好 陕西彩京云互联网科技有限公司 恒生科技互联网指数十大成分股 颐高云石互联网科技
0