File 什么是稀疏文件?我们为什么需要它?

File 什么是稀疏文件?我们为什么需要它?,file,filesystems,system,disk,sparse-file,File,Filesystems,System,Disk,Sparse File,什么是稀疏文件?我们为什么需要它? 我唯一能得到的是,它是一个非常大的文件,而且效率很高(以GB为单位)。它的效率如何?稀疏文件是一个大部分为空的文件,即它包含大量字节,其值为0(零) 在磁盘上,文件的内容存储在固定大小的块中(通常为4kib或更大)。当此类块中包含的所有字节都是0时,实现稀疏文件的文件系统不会将该块存储在磁盘上,而是将信息保存在文件元数据中的某个位置 使用稀疏文件的优点: 空数据块不会占用磁盘空间;它们不作为常规数据块存储,它们的标识符(仅使用几个字节)存储在文件元数据中;这

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

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

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

使用稀疏文件的优点:

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

有关稀疏文件的更多信息,请访问。

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

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

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


编辑:

运行时:

$ dd if=/dev/zero of=output bs=1G count=4
此处的命令将4G块的空字节复制到
输出中。为此:

$ 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
文件时,空字节是由文件系统在运行时动态生成的,它们实际上不是物理存储在磁盘上,并且
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

GNU
dd
在内部使用
lseek
ftruncate
,因此选中truncate(2)和lseek(2)

据我所知,背后的技术是,如果您有大量0字节块的大文件(例如,您正在使用哈希算法计算存储数据的位置),操作系统将不会分配0字节块,只分配您需要的数据。我以前从未使用过它,因为我从未有过像我描述的那样的任务。0字节的块?请解释@nabuchodonossorOk,你也可以在谷歌(microsoft ntfs稀疏文件)上找到解释,但你问了,所以我复制并粘贴了一点:“如果文件中的大部分数据为零,则称其包含稀疏数据集。这样的文件通常非常大,例如,包含要处理的图像数据的文件或高速数据库中的矩阵。包含稀疏数据集的文件的问题在于,文件的大部分不包含有用的数据,因此,它们对磁盘空间的使用效率低下。。。。“那么,当我们用这个方法创建一个文件时,
sudo dd if=/dev/zero of=/swapfile bs=1G count=4
,那么这个文件在磁盘上的大小将为零?对吗?当您使用
sudo dd if=/dev/zero of=/swapfile bs=1G count=4创建文件时,磁盘上的大小不会为零。因为
dd
会将零字节复制到您的文件中。换句话说,您实际上已经将零字节从
/dev/zero
复制到
/swapfile
。然而,这个命令,
ddif=/dev/zero of