在不使用diskutil CLI 包裝器的情況下,我可以獲得所有 USB 設備(可能包括內部 Mac 驅動器)的 BSD 名稱串列的最佳方法是什么?
我不想使用任何與 CLI 界面互動的包裝器,因為這種互動方式非常緩慢且不可靠:

這是我對使用 CLI 包裝器不滿意的一個示例
(比較“DiskUtil CLI Wrapper 所用時間。”和“磁盤仲裁所用時間”)
為我的問題實施解決方案的最佳方法是什么?
使用來自IOReg的資料?
如果是,我如何獲得使用它的連接設備的 BSD 名稱串列?
這是我想要得到的一個例子:
["disk0", "disk0s1", "disk0s2", "disk0s3", "disk1", "disk1s1", "disk1s2", "disk1s3", "disk1s4", "disk2", "disk2s1", "disk2s2", "disk3", "disk3s1", "disk3s1s1", "disk3s2", "disk3s3", "disk3s4", "disk3s5", "disk3s6", "disk4", "disk4s1", "disk4s2", "disk5", "disk5s1", "disk5s2", "disk6", "disk6s1", "disk6s2", "disk10", "disk10s1", "disk10s2", "disk11", "disk11s1"]
目前,我有以下內容:
static func getMountedBSDNames() -> [String] {
guard let session = DASessionCreate(nil) else { return [] }
guard let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil) else { return [] }
var BSDNames: [String] = []
for volumeURL in mountedVolumeURLs {
if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL), let BSDName = DADiskGetBSDName(disk) {
BSDNames.append(
String(cString: BSDName)
)
}
}
return BSDNames
}
但在這種情況下,只有掛載的才會回傳。
我希望那里甚至有那些被驅逐的
uj5u.com熱心網友回復:
我使用 IOReg 查找方法達到了預期的結果:
經過時間
func getDriveBSDNames() -> [String] {
var iterator: io_iterator_t = 0
let matching: CFDictionary = IOServiceMatching(kIOServicePlane)
// Use 'kIOMasterPortDefault' for macOS older than 12.0 Monterey
IOServiceGetMatchingServices(kIOMainPortDefault, matching, &iterator)
var child: io_object_t = IOIteratorNext(iterator)
var BSDNames: [String] = []
while child > 0 {
if let BSDNameAnyObject = IORegistryEntryCreateCFProperty(child, "BSD Name" as CFString, kCFAllocatorDefault, IOOptionBits(kIORegistryIterateRecursively)) {
if let BSDNameString = (BSDNameAnyObject.takeRetainedValue() as? String), BSDNameString.starts(with: "disk") {
BSDNames.append(
BSDNameString
)
}
}
child = IOIteratorNext(iterator)
}
return BSDNames
}
在這種情況下,還需要使用以下方法過濾結果的輸出:(
BSDNameString.starts(with: "disk")
否則會添加一些不必要的設備,例如 en0、anpi0、llw0 等)
uj5u.com熱心網友回復:
請注意,雖然磁盤仲裁框架沒有同步列舉所有磁盤的功能,但它確實通過注冊磁盤外觀回呼來有效地支持異步列舉。根據您的用例,這可能有用也可能沒用 - 當為用戶提供互動式設備串列時,這通常正是您想要的,因為您會自動收到新添加設備的通知。
抱歉,我不使用 Swift,但以下 C 代碼應該很容易理解,以便在其他語言中提出類似的東西。
#include <DiskArbitration/DiskArbitration.h>
#include <stdio.h>
static void disk_appeared(DADiskRef disk, void* context)
{
printf("%s\n", DADiskGetBSDName(disk) ?: "(null)");
}
int main()
{
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DASessionSetDispatchQueue(session, dispatch_get_main_queue());
DARegisterDiskAppearedCallback(session, NULL, disk_appeared, NULL /*context*/);
dispatch_main();
}
請注意,對于沒有 BSD 名稱的 APFS 快照也將呼叫回呼,因此DADiskGetBSDName回傳NULL并且您必須進行一些過濾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/521511.html
