我希望我理解稀疏文件的概念。我也知道cp
命令--sparse=...
然而,当谷歌搜索实际应用程序时,我发现关于使用通用操作系统文件 I/O API 读/写文件的应用程序的透明性的含糊不清的陈述(我的意思是不是在极低的水平,只是 fopen(), fclose () ETC)
阅读博客、解释什么是关于应用程序(例如测试编辑器)如何通过显式向稀疏文件写入零来“破坏”稀疏文件时的解释并不清晰。我认为这就是重点,如果有一个稀疏文件,并且应用程序写入零,则不会进行物理存储。应用程序不必知道这一点,也不必处理间隙等事情,这是文件系统的责任。
问题
假设有一个稀疏的现有文件。它对应用程序是否完全透明?假设有一个 1G 的稀疏文件,它的第一个字节是非零的,所有其他字节都是零。当“普通”应用程序打开该文件时,我想它可以打开它,会看到它的长度为 1G,并且可以寻找到中间(0.5G),因为它不是稀疏的,可以写入一个非零字节中间,保存,关闭,它会在文件系统上保持稀疏,不是吗?
文件会“自动”稀疏吗?我的意思是,一个应用程序只是创建一个文件,然后写入一堆零,然后写入,是否是稀疏的?如果不是,应用程序应该如何将该文件创建为稀疏文件?
在大多数情况下,稀疏文件对程序是透明的,程序不需要关心它们正在处理的文件是否是稀疏文件。
稀疏文件是通过跳过块、在文件中创建空洞而不是通过写入零来创建的。如果程序查找文件末尾,然后导致文件大小更新(通过写入更多数据),或将文件“截断”到比其包含的数据更长的长度,则生成的文件将是稀疏的(如果底层文件系统支持稀疏文件)。
稀疏文件在读取时是透明的(空洞被读取为零),但在写入时不是:将任何数据写入块会强制分配并最终写入。特别是,这意味着如果底层文件系统已满,则在不更改文件长度的情况下写入文件可能会失败。这并不意味着代码编写文件应该有稀疏文件的特殊情况;它只是意味着应该处理所有写入的错误(正如您所期望的那样)。
的 Linux 实现
lseek
提供扩展以允许分析文件中的漏洞。文件不会自动变得稀疏;这就是 GNU
cp
的--sparse
选项存在的原因——它配置cp
为检测零运行本身并在目标中产生漏洞而不是写入它们。如果文件自动变得稀疏,就没有必要了。在您的场景中,一个 1G 的文件在开始时有一个字节的数据将在磁盘上有一个块,包含该字节后跟一个块中适合的许多零。文件的其余部分将是一个大洞。向文件中间写入一个零将分配一个块并用零填充它。然后该文件将包含一个块、一个接近 0.5G 的空洞、另一个块和另一个空洞。