在Linux上分配文件而不清零并且不创建稀疏文件

时间:2018-08-04 02:20:52

标签: linux filesize sparse-file fallocate

我的目标是立即为文件分配大量空间,而不制作稀疏文件。从文件读取应该输出留在可用空间中的垃圾,而不是0。

truncatefallocate都构成稀疏文件。

这可能吗?

1 个答案:

答案 0 :(得分:0)

我们可以避免零吗?

不。这是不可能的。

出于明显的安全原因,内核将清除在删除,截断等操作时释放的扇区。因此,当您分配新文件时,它会自动 全为零。清除可能是虚拟(与物理上在磁盘上写入零相对,特别是因为它在SSD上不起作用-有关详细信息,请参见shred(1))。

要真正快速分配的唯一方法是创建自己的分区并自行管理。如果您当前依赖于ext4或许多其他类似文件系统的许多功能,这并不是一件容易的事。

由于扇区应该已经设置为零,所以在磁盘上分配新的(大)文件时,速度不会受到任何影响。

稀疏文件

根据经验,当您将零写入文件时,它会物理上将零写入磁盘。它根本不会创建稀疏文件。

在软件中,创建稀疏文件需要您使用truncate()/ftruncate()函数来放大文件,并在下一个lseek()之前使用write()在文件末尾。但是,如果您对所有零执行write(),则OS不会尝试将其转换为稀疏文件。

换句话说,您可以在C ++中编写类似的内容,而不会得到稀疏文件:

int fd = open(filename, O_CREAT | O_WRONLY, 0600);
std::vector<uint8_t> buffer(size);
write(fd, buffer.data(), buffer.size());
close(fd);

此代码示例假定一个相对较小的size参数。否则,使用循环会更有效率,并且不太可能消耗您的内存。

在您的控制台中,这使用一种将每个字节写入目标文件的工具进行转换。对于非常大的文件(例如,写入1Tb ...您知道...),它的运行速度会很慢。这是一种工作方式:

head -c${SIZE} /dev/zero >"${OUTPUT}"

请注意,某些专用工具支持稀疏文件。例如:

  • cp可用于复制稀疏文件。
  • dd会在输入文件中查找零,并适当地truncate()来扩大输出而无需写入零。
  • 等等。

当然有充分的理由在磁盘上分配物理文件,即使该操作很慢:

  • 您正在创建数据库文件;在这种情况下使用稀疏文件确实很危险(例如,写入可能在错误的时间 失败),并且分配新的inode的速度,因此您的数据库吞吐量可能会受到影响(尽管这仅在写入和增长数据库文件时发生,与在必要时向文件分配inode相似)。
  • 您正在创建虚拟磁盘;我用稀疏文件测试了这些文件,这太可怕了。至少在装有HDD的旧计算机上,运行VPS时速度太慢了
  • 您正在创建交换文件;使用稀疏文件进行交换确实不是一个好主意(这就像故意寻找麻烦!在分配新块的速度缓慢,文件可能会碎片化的事实,磁盘被损坏的可能性之间)。当您需要交换空间时已满...)