我的目标是立即为文件分配大量空间,而不制作稀疏文件。从文件读取应该输出留在可用空间中的垃圾,而不是0。
truncate
和fallocate
都构成稀疏文件。
这可能吗?
答案 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()
来扩大输出而无需写入零。当然有充分的理由在磁盘上分配物理文件,即使该操作很慢: