8

我有兴趣在 OSX(当前运行 10.9 Mavericks)上迭代所有已挂载的文件系统。我正在寻找类似于 getmntent() 或 mount shell 命令的输出的东西(尽管我想从目标 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() 得到一个结果有答案,我也会对此感兴趣。

4

1 回答 1

9

枚举 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 是关于监控和管理磁盘资产的。使用 DA,您可以在安装或卸载新磁盘时调用。您还可以通过重命名、安装、卸载或弹出它们来管理这些磁盘,以及将自己插入到安装/卸载过程中 - 并可能暂停执行相同操作的请求。但是,正如您所指出的,它不提供列出现有磁盘的界面。一旦您获得了已安装卷的列表,DA 就是一个极好的下一站(当然,取决于您获得该列表的原因!)。

于 2013-11-10T23:01:56.903 回答