6

Currently we use stafs to determine the information about the filesystem volume we are on.

#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;  
}  

We rely on

f_type  

value to make decisions based on whether its HFS+ or APFS or network file system.

However, we are seeing following weird output on three different macOS systems for above small standalone reproducible code.

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

For 2] we get the f_type value for the network path (autofs) as 24 and while in 3] we get f_type as 24 for APFS whch doesnt seem consistent.

This brings us to the qustion, is statfs the correct programmatic way to find the filesystem volume info on macOS ?

If its not, then what would be the right way to do the same ?

4

1 回答 1

9

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

文件系统类型号是一个旧结构;大多数文件系统只是根据它们在系统中注册的顺序分配一个编号。

由于文件系统类型编号现在在最新版本的 MacOS 中在运行时分配,因此您必须使用f_fstypename来确定类型。您会注意到,在 AppKitgetFileSystemInfoForPath方法的签名中,文件系统类型也被表示为字符串。似乎您将获得的最正式的是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::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;  
}  
于 2018-09-12T15:50:54.643 回答