Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Mac OS X上用C语言编程创建稀疏文件?_C_Macos_Filesystems - Fatal编程技术网

如何在Mac OS X上用C语言编程创建稀疏文件?

如何在Mac OS X上用C语言编程创建稀疏文件?,c,macos,filesystems,C,Macos,Filesystems,我想创建一个稀疏文件,这样所有零块在我向它们写入数据之前不会占用实际磁盘空间。可能吗?与其他Unix一样,它是文件系统的一个功能。文件系统支持或不支持所有文件。与Win32不同,您不需要做任何特殊的事情来实现它。与Win32不同的是,使用稀疏文件不会降低性能 在MacOS上,默认文件系统是HFS+,它不支持稀疏文件 更新:MacOS用于支持UFS卷和稀疏文件支持,但已被删除。当前受支持的文件系统都不支持稀疏文件。hdiutil可以处理稀疏图像和文件,但不幸的是,它所链接的框架是私有的 您可以尝试

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

与其他Unix一样,它是文件系统的一个功能。文件系统支持或不支持所有文件。与Win32不同,您不需要做任何特殊的事情来实现它。与Win32不同的是,使用稀疏文件不会降低性能

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


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

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

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

克里斯蒂:~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/privateframes/diskmages.framework/Versions/A/diskmages | awk-F''{print$3}'| c++filt | grep-i稀疏

[……]

CSparseFile::扇区2带(长)

CSparseFile::addIndexNode()

CSparseFile::readIndexNode(长,SparseFileIndexNode*)

CSparseFile::readHeaderNode(CBackingStore*,SparseFileHeaderNode*,无符号长)

[…为了简洁而删节]

后期编辑


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

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

本质上,您管理一个文件,就像操作系统管理磁盘一样,保持作为文件一部分的块链、分配/空闲块位图等

当然,这将导致非优化和较慢的访问,只有在节省空间的要求非常关键并且您有足够的时间编写一组健壮的访问函数时,我才会推荐这种方法

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

如果将(fseek,ftruncate,…)搜索到末尾,则文件大小将增加,而不分配块,直到写入孔为止。但是没有办法创建一个神奇的文件,自动将零块转换成孔。你必须自己做

这可能有助于了解(OpenBSD cp命令插入孔而不是写入零)。

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

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

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;
}
而在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缺少的部分:


关于

看起来OSX支持UDF卷上的稀疏文件。我在OSX10.9上尝试了titaniumdecoy的测试程序,它确实在UDF磁盘映像上生成了一个稀疏文件。另外,并不是说UFS在OSX中不再受支持,所以如果您需要稀疏文件,UDF是唯一一个本机支持的支持它们的文件系统


我还尝试了SMB共享上的程序。当服务器是Ubuntu(ext4文件系统)时,程序会创建一个稀疏文件,但通过SMB的“ls-ls”不会显示这一点。如果你在Ubuntu主机上使用'ls-ls',它确实显示文件是稀疏的。当服务器是Windows XP(NTFS文件系统)时,程序不会生成稀疏文件。

Hmmm…从某种意义上说,数据分叉是unixy分叉,而资源分叉是专用的奇怪文件,不是吗?这两方面都不重要。干杯。是的,“资源叉”是古老的。大多数程序只处理“数据分叉”。UFS已在OSX Lion中删除。更新:macOS现在默认为APFS,后者确实支持它。:)如果要了解任意卷的属性,请使用
getattrlist
获取该卷的
ATTR\u VOL\u CAPABILITIES
属性组,然后检查
VOL\u CAP\u FMT\u SPARSE\u FILES
功能。如前所述,HFS+没有此功能,但APFS有。这在Linux上是正确的,但在默认的MacOSX文件系统HFS+上不是。查看我对这个问题的回答。>如果你搜索(fseek,ftruncate,…)到最后,文件大小将在不分配块的情况下增加。这在OSXI上似乎不正确。我想知道你为什么需要稀疏文件会有帮助。你是指稀疏磁盘映像吗?嗨,我只需要深入研究
hdiutil
private framworks,以便以编程方式附加DMG文件(表示具有自HFS+分区的磁盘映像的文件)。我想知道您是否碰巧在DiskImages框架内挖掘了一些内容,并寻找正确的方法?谢谢
$ 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