macOS:正确的编程方式来确定音量信息

Rec*_*ker 4 c++ filesystems macos posix macos-high-sierra

目前,我们使用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;  
}  
Run Code Online (Sandbox Code Playgroud)

我们依靠

f_type  
Run Code Online (Sandbox Code Playgroud)

根据其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
Run Code Online (Sandbox Code Playgroud)

因为2]我们得到f_type网络路径(autofs)的值为24,而在3]我们得到f_type24为APFS时,似乎并不一致.

这将我们带到qustion,是statfs在macOS上找到文件系统卷信息的正确编程方式吗?

如果不是,那么这样做的正确方法是什么?

Cin*_*its 7

根据vfs_statfs()返回的vfs_filetype 文档,Apple将文件系统类型编号视为一种古老的机制.虽然这对于statfs()来说不是决定性的,但vfs_statfs()更好地记录在案:

文件系统类型编号是旧构造; 大多数文件系统只根据它们在系统中注册的顺序获得一个编号.

由于文件系统类型编号现在在运行时在最新版本的MacOS中分配,因此必须使用它f_fstypename来确定类型.您将注意到,在AppKit getFileSystemInfoForPath方法的签名中,文件系统类型也表示为字符串.看来你要获得的最官方的是Apple自己的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::count << "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;  
}  
Run Code Online (Sandbox Code Playgroud)