macos - 如何在 OSX 上迭代所有挂载的文件系统

标签 macos posix osx-mavericks bsd diskarbitration

我有兴趣在 OSX(目前运行 10.9 Mavericks)上迭代所有已安装的文件系统。我正在寻找类似于 getmntent() 或 mount shell 命令的输出的东西(尽管我想从 objective-c 中执行它,因此解析 shell 命令的输出显然不是最佳的)。

我一直在研究磁盘仲裁框架,似乎可以使用此框架通知我有关挂载和卸载事件的信息。我可能在那里遗漏了一些东西,但我不清楚是否有办法使用磁盘仲裁来迭代现有的已安装文件系统。

我已经使用 getfsent() 进行了探索,它似乎可以提供一种解决方案,但经过测试后我发现我没有从迭代 getfsent() 中获得多个条目。请参阅以下代码:

struct fstab* fsentry;
setfsent();
fsentry = getfsent();
while(fsentry)
{
    //do something with fsentry
    fsentry = getfsent();
}
endfsent();

我在这里得到的唯一条目是/文件系统。我第二次调用 getfsent() 时它返回 NULL,就好像没有更多条目一样。 mount 命令向我展示了其他几个,包括一个已挂载的 cifs/smb 文件系统:
/dev/disk0s2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
//user@<ip address>/public on /Volumes/public (smbfs, nodev, nosuid, mounted by user)

所以似乎 getfsent() 开始做我期望的事情,但由于某种原因停止了?

我总结的问题是:在 OSX 上迭代文件系统的最佳方法是什么?

如果有人对为什么我只从 getfsent() 得到一个结果有答案,我也会对此感兴趣。

最佳答案

有几种不同的方法可以枚举 OS X 上的挂载卷,每种方法都使用不同的 API 集。在最高(也是最简单的)级别,您可以使用 NSFileManager 的 mountedVolumeURLsIncludingResourceValuesForKeys:options: .下面是一个简短的例子:

NSArray *urls = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:@[NSURLVolumeNameKey] options:0];
for (NSURL *url in urls) {
  NSLog(@"Volume mounted at: %@", [url path]);
}

下一个选项将我们带回 C 领域 - 您与原始方法非常接近。在 OS X(和 BSD)上,没有 getmntent() ;相反,有 getmntinfo() ,这惊人地相似。通过 getmntinfo() 列出已安装的卷,您可以执行以下操作:
struct statfs* mounts;
int num_mounts = getmntinfo(&mounts, MNT_WAIT);
if (num_mounts < 0) {
  // do something with the error
}

for (int i = 0; i < num_mounts; i++) {
  NSLog(@"Disk type '%s' mounted at: %s", mounts[i].f_fstypename, mounts[i].f_mntonname);
}

自 10.6 发布以来,我一直同时使用这两个 API。 getmntinfo()总是比[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]更完整: 后者将过滤 /dev以及您可能想知道或不想知道的其他文件系统。但是,对于插入系统的磁盘来说,它通常是可靠的。

正如您所注意到的,DiskArbitration 框架背后的目的是不同的。 DiskArbitration 是关于监视和管理磁盘 Assets 的。使用 DA,您可以在挂载或卸载新磁盘时调用。您还可以通过重命名、挂载、卸载或弹出这些磁盘以及将自己插入挂载/卸载过程来管理这些磁盘 - 并可能暂停执行相同操作的请求。但是,正如您所指出的,它没有提供用于列出现有磁盘的界面。一旦您获得了已安装卷的列表,DA 就是一个很好的下一站(当然,这取决于您获得该列表的原因!)。

关于macos - 如何在 OSX 上迭代所有挂载的文件系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19843238/

相关文章:

macos - 无法在 osx 上使用 luarocks 安装软件包

python - os X 上的 virtualenv 错误

c - 为什么 read() 在 scanf() 之后不起作用?

c - mmap的对齐和粒度

objective-c - 如何为 NSAppearance 制作 "appearance file"?

c - Hook C 函数

xcode - 如何使Xcode在Mac Sierra(10.12.6)上运行

c - 重复使用客户端TCP套接字进行多个HTTP连接

macos - Mac OS X Mavericks 上的 tsung_stats.pl 遇到 "Can' t 定位 Template.pm"错误

macos - OSX 10.9 - Mavericks webdav 客户端锁定问题