如何在Mac OS X上以C编程方式创建稀疏文件?

我想创建一个稀疏文件,使得在我向它们写入数据之前,全零块不会占用实际的磁盘空间。 可能吗?

和其他Unix一样,它是文件系统的一个特性。 文件系统支持所有文件,或者不支持。 与Win32不同,您无需执行任何特殊操作即可实现。 与Win32不同,使用稀疏文件没有性能损失。

在MacOS上,默认文件系统是HFS +,它支持稀疏文件。

更新: MacOS用于支持具有稀疏文件支持的UFS卷,但已被删除。 当前支持的文件系统都不支持稀疏文件。

对于默认的Mac OS X文件系统(HFS +)是否支持文件中的漏洞,似乎存在一些混淆。 以下程序表明情况并非如此。

#include  #include  #include  #include  void create_file_with_hole(void) { int fd = open("file.hole", O_WRONLY|O_TRUNC|O_CREAT, 0600); write(fd, "Hello", 5); lseek(fd, 99988, SEEK_CUR); // Make a hole write(fd, "Goodbye", 7); close(fd); } void create_file_without_hole(void) { int fd = open("file.nohole", O_WRONLY|O_TRUNC|O_CREAT, 0600); write(fd, "Hello", 5); char buf[99988]; memset(buf, 'a', 99988); write(fd, buf, 99988); // Write lots of bytes write(fd, "Goodbye", 7); close(fd); } int main() { create_file_with_hole(); create_file_without_hole(); return 0; } 

该程序创建两个文件,每个文件长度为100,000个字节,其中一个文件的漏洞为99,988字节。

在HFS +分区上的Mac OS X 10.5上,两个文件占用相同数量的磁盘块(200):

 $ ls -ls total 400 200 -rw------- 1 user staff 100000 Oct 10 13:48 file.hole 200 -rw------- 1 user staff 100000 Oct 10 13:48 file.nohole 

而在CentOS 5上,没有空洞的文件比另一个消耗88个磁盘块:

 $ ls -ls total 136 24 -rw------- 1 user nobody 100000 Oct 10 13:46 file.hole 112 -rw------- 1 user nobody 100000 Oct 10 13:46 file.nohole 

该线程成为有关稀疏文件的综合信息源。 这是Win32缺少的部分:

带有例子的体面文章

估计使文件稀疏是否有意义的工具

问候

hdiutil可以处理稀疏的图像和文件,但不幸的是它链接的框架是私有的。

您可以尝试定义下面的DiskImages框架定义的外部符号,但这很可能不适用于生产代码,而且由于框架是私有的,因此您必须对其用例进行反向工程。

cristi:~diciu $ otool -L / usr / bin / hdiutil

/ usr / bin / hdiutil:/System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages(兼容版本1.0.8,当前版本194.0.0)[..]

cristi:~diciu $ nm /System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages | awk -F”'{print $ 3}’| c ++ filt | grep -i稀疏

[..]

CSparseFile :: sector2Band(long long)

CSparseFile :: addIndexNode()

CSparseFile :: readIndexNode(long long,SparseFileIndexNode *)

CSparseFile :: readHeaderNode(CBackingStore *,SparseFileHeaderNode *,unsigned long)

[…为简洁起见]

稍后编辑

可以将hdiutil用作外部进程,并让它为您创建稀疏磁盘映像。 然后,在C进程中,您将在(已安装的)稀疏磁盘映像中创建一个文件。

如果您想要可移植性,最后的方法是编写自己的访问函数,以便管理索引和一组块。

本质上,您管理单个文件,因为操作系统管理磁盘,保留作为文件一部分的块链,分配/空闲块的位图等。

当然这会导致非优化和较慢的访问,只有节省空间的要求绝对关键并且你有足够的时间来编写一组强大的访问函数时,我才会推荐这个应用程序。

即使在这种情况下,我也会首先调查您的问题是否需要不同的解决方案。 您可能应该以不同方式存储数据吗?

如果你寻找(fseek,ftruncate,…)到最后,文件大小将增加而不分配块,直到你写入孔。 但是没有办法创建一个自动将零块转换为空洞的魔术文件。 你必须自己做。

这可能有助于查看(OpenBSD cp命令插入孔而不是写入零)。 补丁

看起来OS X支持UDF卷上的稀疏文件。 我在OS X 10.9上尝试了titaniumdecoy的测试程序,它确实在UDF磁盘映像上生成了一个稀疏文件。 此外,OS X中不再支持UFS,因此如果您需要稀疏文件,UDF是唯一支持它们的本机支持的文件系统。

我也尝试过关于SMB股票的计划。 当服务器是Ubuntu(ext4文件系统)时,程序会创建一个稀疏文件,但是通过SMB的’ls -ls’不会显示该文件。 如果你在Ubuntu主机上做’ls -ls’,它确实显示文件是稀疏的。 当服务器是Windows XP(NTFS文件系统)时,程序不会生成稀疏文件。