26

什么是稀疏文件,我们为什么需要它?我唯一能得到的是它是一个非常大的文件并且它很高效(以千兆字节为单位)。效率如何?

4

2 回答 2

30

假设您有一个包含许多空字节的文件\x00。这许多空字节\x00被称为空洞。存储空字节效率不高,我们知道文件中有很多空字节,那么为什么要将它们存储在存储设备上呢?我们可以改为存储描述这些零的元数据。当一个进程读取文件时,这些零字节块会动态生成,而不是存储在物理存储中(查看 Wikipedia 中的此示意图):

稀疏文件 - 维基百科

这就是稀疏文件高效的原因,因为它不会将零存储在磁盘上,而是保存足够的数据来描述将要生成的零。

注意:对于稀疏文件,逻辑文件大小大于物理文件大小。这是因为我们没有将零物理存储在存储设备上。


编辑:

当你运行时:

$ dd if=/dev/zero of=output bs=1G count=4

此处的命令将 4G 空字节块复制到output. 要看到:

$ stat output
File: ouput
  Size: 4294967296      Blocks: 8388616    IO Block: 4096   regular file
--omitted--

您可以看到该文件分配了8388616个块,这些块只存储从中复制的空字节/dev/zero,它们确实占用了物理磁盘空间,它们是存储在磁盘上的空洞(稀疏零)。dd做了你要求的,将数据块从一个文件复制到另一个文件。

现在,运行此命令来检测漏洞并使文件就地稀疏:

$ fallocate -d output
$ stat output
File: swapfile
  Size: 4294967296      Blocks: 0          IO Block: 4096   regular file
--omitted--

你注意到什么了吗?现在的块数为 0,因为仅存储空字节的块已被释放。记住,output的块什么都不存储,只有一堆空零,fallocate -d检测到只包含空零的块并释放它们,因为这个文件的所有块都包含零,所以它们都被释放了。

还要注意大小是如何保持不变的。这是文件的逻辑(虚拟)大小,而不是它在磁盘上的大小。重要的是要知道它现在output不占用物理存储空间,它分配了 0 个块,因此我并没有真正使用磁盘空间。运行后保留的大小,fallocate -d因此当您稍后从文件中读取时,您会得到文件系统在运行时为您生成的空字节。然而,物理大小output为零,它不使用数据块。

请记住,当您读取output文件时,空字节是由文件系统在运行时动态生成的,它们并没有真正物理存储在磁盘上,并且报告的文件大小stat是逻辑大小,物理大小为零output。在这种情况下,当进程读取文件时,文件系统必须生成 4G 的空字节。

要使用以下方法生成稀疏文件dd

$ dd if=/dev/zero of=output2 bs=1G seek=0 count=0
$ stat 
stat output2
  File: output2
  Size: 4294967296      Blocks: 0          IO Block: 4096   regular file

GNUdd内部使用lseekand ftruncate,因此请检查 truncate(2) 和 lseek(2)。

于 2017-09-05T16:42:08.140 回答
5

稀疏文件是一个大部分为空的文件,即它包含值为0(零)的大块字节。

在磁盘上,文件的内容存储在固定大小的块中(通常为 4 KiB 或更大)。当这样一个块中包含的所有字节都是0时,实现稀疏文件的文件系统不会将该块存储在磁盘上,而是将信息保存在文件元数据中的某个位置。

使用稀疏文件的优点:

  • 空数据块不占用磁盘空间;它们不作为常规数据块存储,它们的标识符(仅使用几个字节)存储在文件元数据中;这样可以为每个空块节省 4 KiB 的磁盘空间(或更多);
  • 从稀疏文件中读取空数据块不需要时间;发生这种情况是因为没有从磁盘读取数据;由于文件系统知道块中的所有字节都是0,它只是设置0输入缓冲区中的所有字节并且数据准备好了;无需访问慢速存储设备;
  • 将空数据块写入稀疏文件不需要时间;在写入时,文件系统检测到该块为空(其所有字节均为0)并将块 ID 放入空块列表(在文件元数据中);没有数据写入磁盘。

有关稀疏文件的更多信息,请参见Wikipedia 页面

于 2017-09-04T12:32:02.107 回答