macOS:确定卷信息的正确编程方式
macOS : Correct programmatic way to determine volume info
目前我们使用 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]
中,我们得到 f_type
作为 APFS 的 24 而不是看起来一致。
这给我们带来了一个问题,statfs
是在 macOS 上查找文件系统卷信息的正确编程方式吗?
如果不是,那么正确的做法是什么?
根据 vfs_statfs() 返回的 documentation for vfs_filetype,Apple 将文件系统类型编号视为一种古老的机制。虽然这对于 statfs() 不是确定的,但更好地记录了 vfs_statfs():
Filesystem type numbers are an old construct; most filesystems
just get a number assigned based on the order in which they are
registered with the system.
由于在最新版本的 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;
}
目前我们使用 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]
中,我们得到 f_type
作为 APFS 的 24 而不是看起来一致。
这给我们带来了一个问题,statfs
是在 macOS 上查找文件系统卷信息的正确编程方式吗?
如果不是,那么正确的做法是什么?
根据 vfs_statfs() 返回的 documentation for vfs_filetype,Apple 将文件系统类型编号视为一种古老的机制。虽然这对于 statfs() 不是确定的,但更好地记录了 vfs_statfs():
Filesystem type numbers are an old construct; most filesystems just get a number assigned based on the order in which they are registered with the system.
由于在最新版本的 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;
}