如何在Swift中获取磁盘标识符

时间:2016-02-17 21:40:44

标签: swift macos

我想查找附加驱动器的标识符 - 如终端命令diskutil list

中所示
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *1.0 TB     disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS SSHD OSX                511.7 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
   4:                  Apple_HFS SSHD OSX NEW            511.0 GB   disk0s4
   5:                 Apple_Boot Recovery HD             650.0 MB   disk0s5

到目前为止,我已设法编写此代码:

  var volume_stack = [NSURL]()



  volume_stack = NSFileManager.defaultManager().mountedVolumeURLsIncludingResourceValuesForKeys([NSURLVolumeNameKey, NSURLVolumeIdentifierKey], options: [])!
  for disk: NSURL in volume_stack {
    do {
        var info: Dictionary = [String : AnyObject]()
        info = try disk.resourceValuesForKeys([NSURLVolumeIdentifierKey])
        for (key, value) in info {
             var s_value = String(data: value as! NSData, encoding: NSUTF8StringEncoding)
             print("key: \(key) value: \(s_value)")
        }
    }
    catch {
        print ("ERROR")
    }
 }

但输出是:

key: NSURLVolumeIdentifierKey value: Optional("gEd\0\0\0\0\0")
key: NSURLVolumeIdentifierKey value: nil
key: NSURLVolumeIdentifierKey value: nil
key: NSURLVolumeIdentifierKey value: Optional("sHg\0\0\0\0\0")

ivar value而非s_value的日志提供

key: NSURLVolumeIdentifierKey value: <67456400 00000000>
key: NSURLVolumeIdentifierKey value: <c6236500 00000000>
key: NSURLVolumeIdentifierKey value: <69986600 00000000>
key: NSURLVolumeIdentifierKey value: <73486700 00000000>

我可以告诉它NSData。对于编写得很糟糕的代码表示歉意,但它是我的第一个Swift应用程序,而且我已经在圈子里四处走动,所以它变得有点简单。有没有办法获得标识符列中列出的String

2 个答案:

答案 0 :(得分:2)

使用DiskArbitration.framework

  

在较高级别,您可以使用磁盘仲裁框架:

     
      
  • 接收磁盘相关事件的通知(磁盘弹出,用于   例子)并参与仲裁过程(防止磁盘)   例如,弹射)。
  •   
  • 获取有关磁盘和操作的信息   磁盘(例如,请求弹出磁盘)。
  •   

首先使用DASessionCreate创建一个全局会话,然后为每个已安装的卷创建一个带有DADiskCreateFromVolumePath的磁盘引用,并获取带有DADiskGetBSDName的BSD名称(标识符)。将C字符串转换为String,您就完成了。

if let session = DASessionCreate(kCFAllocatorDefault) {
    let mountedVolumeURLs = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil)!
    for volumeURL in mountedVolumeURLs {
        if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumeURL as CFURL),
            let bsdname = DADiskGetBSDName(disk),
            let bsdString = String(cString : bsdName) {
               print(volumeURL.path, bsdString)
            }
        }
    }
}

另一种合适的方法是解析IORegistry。

答案 1 :(得分:0)

另一种(可能更简单)的方法是调用BSD函数statfs()。在普通C语言中,您将使用:

struct statfs fsinfo;
statfs("/", &fsinfo);
printf("root device path: %s\n", fsinfo.f_mntfromname);

这将显示类似“ / dev / disk1s3”的内容

下面是从Swift调用statfs的示例

import Darwin

extension String {
    /// See https://oleb.net/blog/2017/12/swift-imports-fixed-size-c-arrays-as-tuples/
    init<T>(tupleOfCChars: T, length: Int = Int.max) {
        self = withUnsafePointer(to: tupleOfCChars) { pointer -> String in
            let count = MemoryLayout<T>.size / MemoryLayout<CChar>.size

            return pointer.withMemoryRebound(to: CChar.self, capacity: count) { cCharPointer in
                return String(cString: cCharPointer)
            }
        }
    }
}

var fsInfo = statfs()
statfs("/", &fsInfo)
let fileSystemMountName = String(tupleOfCChars: fsInfo.f_mntfromname)

print(fileSystemMountName) // => /dev/disk1s5