跳转到内容

稀疏文件

本页使用了标题或全文手工转换
维基百科,自由的百科全书
稀疏文件:不需要保存空块。

简介

[编辑]

稀疏文件(英语:sparse file),一种文件类型。

稀疏文件需要文件系统的支持,与操作系统的实现。

具体细节

[编辑]

前置概念:

  • 块:操作系统进行存储数据读写时的基本单位,也称为簇。
  • 零字节:数值为 0 的字节,即 8 个二进制位全部为 0,也被称为空字节。
  • 空块:由连续的零字节组成的块。
  • 文件的逻辑占用空间:操作系统对外界呈现的文件大小。
  • 文件的物理占用空间:物理存储对外界呈现的文件大小。
稀疏文件的特性,即与普通文件的差异,在于存储空块时的不同:
  • 普通文件:操作系统会为空块分配物理存储空间。文件的物理占用空间,相当于文件的逻辑占用空间。
  • 稀疏文件:操作系统不会为空块分配物理存储空间,而是使用文件系统元数据,标记出空块在逻辑上存在的位置。文件的物理占用空间,相当于文件的逻辑占用空间,再减去空块部分。
    • 当程序读取标记的区域时,操作系统会直接把空块当作真正位于物理存储空间的数据,直接返回给程序,效果等同于读取实际物理存储的空块。中间的操作对程序而言是透明的,它只是按照普通文件的方式读取,看到的是连续的零字节,感觉不到与普通文件的差异。

使用场景与支持情况

[编辑]

使用场景:

  • 虚拟机磁盘文件,如:VMDK(VMware)、VHD/VHDX(Hyper-V)、qcow2(QEMU/KVM)
  • BT下载
  • 容器镜像与层存储
  • 数据库、日志的空间预分配

受支持的文件系统:

优势

[编辑]

稀疏文件的优势是,它分配的存储空间只在需要时使用:这样节省了磁盘空间,并且可以创建很大的文件,即使文件系统中的可用空间不足。这也减少了首次写入的时间,因为系统不会分配“跳过”的空间。如果初始分配需要写入全零到空间,这也使得系统不必写入两次。

缺点

[编辑]

稀疏文件的缺点包括:稀疏文件可能碎片化;文件系统的空余空间报告可能产生误导;包含稀疏文件的文件系统被填满可能产生意外效果,例如只是重写现有文件的内容时遭遇磁盘已满或超出配额错误——开发者未预料到文件可能被稀疏;使用非显式支持的计算机程序复制稀疏文件可能会复制整个内容,即未压缩的文件大小,包括未实际在磁盘上分配的零空间——也就是使稀疏文件失去稀疏属性。稀疏文件也不是被所有备份软件和应用支持。不过,VFS的实现回避了先前两个缺点。在Windows上加载稀疏的可执行文件(exe或dll)可能需要更多时间,因为文件不被映射到内存和缓存。

Unix中的稀疏文件

[编辑]

稀疏文件通常对用户透明(不可见)处理。但在某些情况下,稀疏文件会与正常文件显现出差异。

创建

[编辑]

Unix命令:

 dd of=sparse-file bs=1k seek=5120 count=0

将创建一个5MB大小的文件,但不在磁盘上存储数据(仅存储元数据)。(GNU dd也有此表现,因为它调用ftruncate来设置文件大小;其他实现可能是只创建一个空文件)。 如果truncate命令可用,也可以使用它:

 truncate -s 5M <filename>

删除

[编辑]

ls命令的-s选项会以块为单位显示已占用的空间。

 ls -ls sparse-file

或者,du命令将打印占用的空间,而ls打印明面的大小。在一些非标准的du版本中,--block-size=1选项打印字节而非块单位的占用空间,因而可以与ls的输出比较:

 du --block-size=1 sparse-file
 ls -l sparse-file

复制

[编辑]

一般来说,GNU版本的cp是检测文件是否为稀疏文件的较好方式,所以

cp sparse-file new-file

创建一个新文件,它将是稀疏性质。但是,GNU版本的cp有--sparse=WHEN选项。[4]这尤为有用,如果一个已保存文件包含长串零块且非稀疏方式保存(即长串的零块已被完全写入并占用磁盘空间)。用此命令可以节省磁盘空间:

cp --sparse=always file1 file1_sparsed

在某些例如FreeBSD的cp实现中,--sparse选项不被支持,将始终展开稀疏文件。这些系统上的可行替代方案是使用rsync的--sparse选项[5]代替cp。遗憾的是--sparse无法与--inplace组合使用,因此通过网络rsync巨大文件时始终会浪费网络和磁盘带宽。

通过标准输入

[编辑]
 cp --sparse=always /proc/self/fd/0 new-sparse-file < somefile

Windows的NTFS

[编辑]

如果一个文件的大部分数据是0,则这个文件被称包含了稀疏数据集。 文件压缩可以有效率地表示稀疏文件,但压缩与解压会带来时间代价。 NTFS文件系统支持稀疏文件表示,并对文件的读写操作透明。

为确定文件系统是否支持稀疏文件,调用GetVolumeInformation函数,使用lpFileSystemFlags参数,检查返回结果对应于FILE_SUPPORTS_SPARSE_FILES比特标志。 DWORD dwFileSystemFlags = 0; BOOL bOk = GetVolumeInformation("C:\\", NULL, 0, NULL, NULL, &dwFileSystemFlags, NULL, 0); bOk = dwFileSystemFlags&FILE_SUPPORTS_SPARSE_FILES ; 判断一个文件是否是稀疏文件:GetFileInformationByHandle

大部分文件,在改变它的EndOfFile的时候,中间的空白会被操作系统填0,也就是说,如果用SetFilePointer和SetEndOfFile来产生一个很大的文件,那么这个文件它占用的是真正的磁盘空间,即使里面全是0,系统默认的也会在DeviceIoControl()中的ControlCode里用FSCTL_SET_ZERO_DATA标记,这个标记使得那些文件空洞被0所填充。为了节省磁盘空间,必须把一个文件声明为稀疏文件,以便让系统把那些无用的0字节压缩,并释放相应的磁盘空间,这需要用DeviceIoControl()将标记改为FSCTL_SET_SPARSE。

参见

[编辑]

参考资料

[编辑]
  1. ^ https://man7.org/linux/man-pages/man2/fallocate.2.html.  缺少或|title=为空 (帮助)
  2. ^ https://learn.microsoft.com/en-us/windows/win32/fileio/sparse-files.  缺少或|title=为空 (帮助)
  3. ^ https://developer.apple.com/documentation/foundation/about-apple-file-system?language=objc#File-system-operations.  缺少或|title=为空 (帮助)
  4. ^ Jim Meyering. GNU coreutils/cp: Accept new option, --sparse={never,auto,always}, to control creation of sparse files.. 1995-12-21 [2016-06-17]. 
  5. ^ Tridgell, Andrew. rsync: hard links, better sparse handling, FERROR and FINFO. 1996-06-29 [2016-06-17]. (原始内容存档于2016-06-25). 

外部链接

[编辑]