稀疏文件：空字节不需要保存，只需要通过元数据定义。
**稀疏文件**（英語：）是一种计算机文件，它能尝试在文件内容大多为空时更有效率地使用文件系统的空间。它的原理是以简短的信息（元数据）表示空数据块，而不是在在磁盘上占用实际空间来存储空数据块。只有真实（非空）的数据块会按原样写入磁盘。

在读取稀疏文件时，文件系统会按元数据在运行时将这些透明转换为"真实"的数据块，即填充为零。应用程序不会察觉这个转换。

大多数现代的文件系统支持稀疏文件，包括大多数Unix变种和NTFS。苹果的HFS+不提供稀疏文件支持，但在OS X中，虛擬檔案系統层支持在任何受支持文件系统中存储稀疏文件，包括HFS+。2016年6月在WWDC宣布的苹果文件系统（APFS）支持稀疏文件。稀疏文件常被用在磁盘映像、数据库快照、日志文件和科学应用中。

优势
--

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

缺点
--

稀疏文件的缺点包括：稀疏文件可能碎片化；文件系统的空余空间报告可能产生误导；包含稀疏文件的文件系统被填满可能产生意外效果，例如只是重写现有文件的内容时遭遇磁盘已满或超出配额错误——开发者未预料到文件可能被稀疏；使用非显式支持的计算机程序复制稀疏文件可能会复制整个内容，即未压缩的文件大小，包括未实际在磁盘上分配的零空间——也就是使稀疏文件失去稀疏属性。稀疏文件也不是被所有备份软件和应用支持。不过，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`选项。这尤为有用，如果一个已保存文件包含长串零块且非稀疏方式保存（即长串的零块已被完全写入并占用磁盘空间）。用此命令可以节省磁盘空间：

```
cp --sparse=always file1 file1_sparsed
```

在某些例如FreeBSD的cp实现中，`--sparse`选项不被支持，将始终展开稀疏文件。这些系统上的可行替代方案是使用rsync的`--sparse`选项代替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. ↑  Giampaolo, Dominic.  (PDF). Morgan Kaufmann Publishers. 1999  [2016-06-24]. ISBN 9781558604971. （原始内容 (PDF)存档于2017-02-13）.
2. ↑ . Apple Inc.  [2016-06-17]. （原始内容存档于2016-06-13）.
3. ↑  Jim Meyering.. 1995-12-21  [2016-06-17].
4. ↑  Tridgell, Andrew.. 1996-06-29  [2016-06-17]. （原始内容存档于2016-06-25）.

外部链接
----

* NTFS Sparse Files For Programmers （页面存档备份，存于）
* Creating sparse files in Windows Server using fsutil （页面存档备份，存于）
* Creating sparse files in Solaris using mkfile(1M) （页面存档备份，存于）
* View the Size of the Sparse File of a Database Snapshot （页面存档备份，存于）
* SEEK\_HOLE or FIEMAP: Detecting holes in sparse files （页面存档备份，存于）
* virtsync is a commercial solution to rsync's --sparse and --inplace issue.
* SparseChecker - Utility that allows to manage the sparse files on NTFS file system
* Phantom - a program to convert files to sparse files to reduce disk space （页面存档备份，存于）
* ArchLinux Wiki: Sparse file （页面存档备份，存于）