macOS:正确的程序化确定卷信息的方法

6

目前我们使用 stafs 来确定我们所在的文件系统卷的信息。

#include <string>  
#include <iostream>  
#include <sys/mount.h>  
#include <sys/param.h>  

void statFileSys(const std::string f)  
{  
    struct statfs fileStat;  
    if(statfs(f.data(),&fileStat) == 0)  
    {  
        std::cout << "File type: " << fileStat.f_type <<'\n';  
        std::cout << "File system name: "<<fileStat.f_fstypename << '\n';  
    }  
    else  
    {  
        std::cout << "statfs failed !!!"<<std::endl;  
    }  
}  

int main()  
{  
    statFileSys("/some/network/path");  
    statFileSys("/tmp");  

    return 0;  
}  

我们依赖于
f_type  

需要根据文件系统是HFS+、APFS还是网络文件系统来做决策的值。

然而,我们在三台不同的macOS系统上看到了上述小型独立可复制代码的以下怪异输出。

1]
macOS 10.12 + HFS+
File type: 25
File system name: autofs
File type: 23
File system name: hfs

2]
macOS 10.13 (beta) + HFS+
File type: 24
File system name: autofs
File type: 23
File system name: hfs

3]
macOS 10.13 (beta) + APFS
File type: 25
File system name: autofs
File type: 24
File system name: apfs

对于2],我们得到了网络路径(autofs)的f_type值为24,而在3]中,我们得到了APFS的f_type值为24,这似乎不一致。
这就引出了一个问题,statfs是否是在macOS上查找文件系统卷信息的正确编程方式?
如果不是,那么什么才是正确的方法?

你使用 f_type 而不是 f_fstypename[] 来进行决策,有什么原因吗? - Thunderwood
我还没有确定这一点,但我目前的猜测是f_type正在提供分区号或类似的内容,这可能会因为磁盘挂载过程而有所不同。这意味着您可能只能将其用作比较以确保它是相同的分区。再次强调,这只是一个理论,但请查看此页面并检查终端给出的数字与您的程序是否相同:https://ss64.com/osx/diskutil.html - Thunderwood
1个回答

9
根据vfs_statfs()函数返回的文件系统类型号,参考文档,苹果认为文件系统类型号是一种古老机制。尽管这对于statfs()函数不是绝对的,但vfs_statfs()函数有更好的文档说明:

文件系统类型号是一个旧构造;大多数文件系统只是根据其在系统中注册的顺序而被分配一个数字。

由于最近版本的MacOS在运行时分配文件系统类型号,因此您必须使用f_fstypename来确定文件系统类型。您会注意到,在AppKit的getFileSystemInfoForPath方法的签名中,文件系统类型也表示为字符串。似乎您能够得到最官方的信息只能通过苹果自己的API。
#include <string>  
#include <iostream>  
#include <sys/mount.h>  
#include <sys/param.h>  

void statFileSys(const std::string f)  
{  
    struct statfs fileStat;  
    if(statfs(f.data(),&fileStat) == 0)  
    {  
        if(!strcmp(fileStat.f_fstypename, "apfs") )
            std::cout << "File system is APFS << std::endl;
        else if(!strcmp(fileStat.f_fstypename, "hfs") )
            std::cout << "File system is HFS+ << std::endl;
        else if(!strcmp(fileStat.f_fstypename, "nfs") )
            std::cout << "File system is NFS << std::endl;
        else if(!strcmp(fileStat.f_fstypename, "cd9660") )
            std::cout << "File system is CD-ROM << std::endl;
        else
            std::cout << "We weren't looking for a " 
                << fileStat.f_fstypename << " were we?" << std::endl;
    }  
    else  
    {  
        std::cout << "statfs failed !!!"<<std::endl;  
    }  
}  

int main()  
{  
    statFileSys("/some/network/path");  
    statFileSys("/tmp");  

    return 0;  
}  

没有人评论“建议的编辑队列已满”,还需要进行一些编辑吗?例如,“std::count”是一个要创建的函数吗? - Arun Panneerselvam
不好意思,我不明白你在说什么。并没有“std::count”这个函数。 - Cinder Biscuits
提到了这一行代码,std::count<<“我们没有在寻找一个”,有拼写错误和'if'语句中的闭合括号。 - Arun Panneerselvam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接