【问题标题】:macOS : Correct programmatic way to determine volume infomacOS:确定音量信息的正确编程方式
【发布时间】:2020-10-30 12:27:33
【问题描述】:

目前我们使用 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[] 进行决策?
  • 我还没有确定这一点,但到目前为止我的猜测是 f_type 给出了一个分区号或类似的东西,这可能会根据磁盘安装过程而有所不同。这意味着您可能无法使用它,除非作为比较以确保其相同的分区。同样,这只是一个理论,但请查看此页面并检查终端给出的数字与您的程序:ss64.com/osx/diskutil.html

标签: c++ macos filesystems posix macos-high-sierra


【解决方案1】:

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

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

由于文件系统类型编号现在在最新版本的 MacOS 中在运行时分配,您必须使用f_fstypename 来确定类型。您会注意到,在 AppKit 的 getFileSystemInfoForPath 方法的签名中,文件系统类型也被表示为字符串。看来您将获得的最官方的 API 是 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;  
}  

【讨论】:

  • 没有人评论“建议的编辑队列已满”,需要稍微编辑一下吗?例如,'std::count' 是一个函数吗?
  • 不知道你在说什么。没有“std::count”。
  • 提到了这一行,std::count
猜你喜欢
  • 2010-09-18
  • 1970-01-01
  • 2020-03-29
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 2023-03-06
  • 2013-07-26
相关资源
最近更新 更多