代码之家  ›  专栏  ›  技术社区  ›  robottobor

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

  •  8
  • robottobor  · 技术社区  · 16 年前

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

    7 回复  |  直到 9 年前
        1
  •  7
  •   David Kanarek    9 年前

    和其他unix一样,它是文件系统的一个特性。文件系统要么支持所有文件,要么不支持。不像win32,您不必做任何特殊的事情来实现它。与Win32不同的是,使用稀疏文件不会造成性能损失。

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

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

        2
  •  11
  •   titaniumdecoy Mr. T    16 年前

    对于默认的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;
    }
    

    该程序创建两个文件,每个文件的长度为100000字节,其中一个文件的孔为99988字节。

    在Mac OS X 10.5的HFS+分区上,两个文件占用相同数量的磁盘块(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
        3
  •  2
  •   opal    14 年前

    这个线程成为关于稀疏文件的全面信息源。以下是Win32缺少的部分:

    Decent article with examples

    Tool that estimates if it makes sense to make file as sparse

    当做

        4
  •  1
  •   diciu    16 年前

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

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

    克里斯蒂:~diciu$otool-l/usr/bin/hdiutil

    /美国存托凭证 /system/library/privateframeworks/diskimages.framework/versions/a/diskimages(兼容性版本1.0.8,当前版本194.0.0) […]

    CRISTI:~ DICUU $ NM/系统/库/私有框架/ DISKIGIDES。框架/版本/ A/DISKIMAGE,AWK-F’’{打印3美元} c++FILT.GRIP-I稀疏

    […]

    CSParseFile::Sector2Band(长-长)

    CSParseFile::AddIndexNode()。

    csparsefile::readindexnode(长、稀疏、索引节点*)

    csparsefile::readheadernode(cbackingstore*,sparsefileheadernode*,unsigned long)

    …简洁明了]

    后期编辑

    能够 使用hdiutil作为外部进程,让它为您创建一个稀疏的磁盘映像。然后从C进程在(挂载的)稀疏磁盘映像中创建一个文件。

        5
  •  0
  •   Remo.D    16 年前

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

    本质上,当操作系统管理磁盘时,您管理一个文件,保留作为文件一部分的块链、已分配/可用块的位图等。

    当然,这将导致非优化和较慢的访问速度,只有在节省空间的要求是绝对关键的,并且您有足够的时间编写一组健壮的访问功能时,我才会重新使用此应用程序。

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

        6
  •  0
  •   user10392    16 年前

    如果您寻找(fseek,ftruncate,…)到结束,文件大小将增加,而不分配块,直到您写入孔。但是没有办法创建一个自动将零块转换成孔的魔法文件。你得自己动手。

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

        7
  •  0
  •   eladts    11 年前

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

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