Получить список подключенных томов с помощью Swift?

Кто-нибудь знает, как получить список всех съемных томов, смонтированных с помощью Swift?

Я уже пробовал это, но он возвращает список всех файлов и подпапок внешних драйверов:

let filemanager:NSFileManager = NSFileManager()
        let files = filemanager.enumeratorAtPath("/Volumes")


        while let file = files?.nextObject() {
            println(file)
            menu.addItem(NSMenuItem(title: file as! String, action: Selector(""), keyEquivalent: ""))
        }

3 ответа

Решение

Это печатает список всех подключенных томов:

let filemanager = NSFileManager()
let keys = [NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, NSURLVolumeIsEjectableKey]
let paths = filemanager.mountedVolumeURLsIncludingResourceValuesForKeys(keys, options: nil)
if let urls = paths as? [NSURL] {
    for url in urls {
        println(url)
    }
}

Конечно, вы можете фильтровать, чтобы получить только пути внутри каталога "Тома":

let filemanager = NSFileManager()
let keys = [NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, NSURLVolumeIsEjectableKey]
let paths = filemanager.mountedVolumeURLsIncludingResourceValuesForKeys(keys, options: nil)
if let urls = paths as? [NSURL] {
    for url in urls {
        if url.relativePath?.pathComponents.count > 1 {
            if url.relativePath?.pathComponents[1] == "Volumes" {
                println(url)
            }
        }
    }
}

А в Swift 2 есть два отличия: проход [] вместо nil для параметров файлового менеджера, и нет необходимости приводить массив NSURL:

let filemanager = NSFileManager()
let keys = [NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, NSURLVolumeIsEjectableKey]
let paths = filemanager.mountedVolumeURLsIncludingResourceValuesForKeys(keys, options: [])
if let urls = paths {
    for url in urls {
        if url.relativePath?.pathComponents.count > 1 {
            if url.relativePath?.pathComponents[1] == "Volumes" {
                print(url)
            }
        }
    }
}

Обновление для Swift 2.1

let keys = [NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, NSURLVolumeIsEjectableKey]
let paths = NSFileManager().mountedVolumeURLsIncludingResourceValuesForKeys(keys, options: [])
if let urls = paths {
    for url in urls {
        if let components = url.pathComponents
            where components.count > 1
            && components[1] == "Volumes" {
                print(url)
        }
    }
}

Обновление для Swift 3

let keys: [URLResourceKey] = [.volumeNameKey, .volumeIsRemovableKey, .volumeIsEjectableKey]
let paths = FileManager().mountedVolumeURLs(includingResourceValuesForKeys: keys, options: [])
if let urls = paths {
    for url in urls {
        let components = url.pathComponents
        if components.count > 1
           && components[1] == "Volumes"
        {
            print(url)
        }
    }
}
      let keys: [URLResourceKey] = [
    .volumeNameKey,
    .volumeIsRemovableKey,
    .volumeIsEjectableKey,
    .volumeAvailableCapacityKey,
    .volumeTotalCapacityKey,
    .volumeUUIDStringKey,
    .volumeIsBrowsableKey,
    .volumeIsLocalKey,
    .isVolumeKey,
]

let manager = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: keys)
if let urls = manager {
    print(urls)
}

Этот код отлично работает для MacOS, однако на стороне iOS он всегда возвращает nil. Есть ли какое-либо известное обходное решение? Спасибо!

В системах Unix объект файловой системы с номером системного файла 2 является монтированием, независимо от удаленного (nfs, smb, afp) или локального монтирования.

Вот пример:

      let path = "/System/Volumes/Preboot"
let systemAttributes = try FileManager.default.attributesOfItem(atPath: String(describing: path))
if let fileSystemFileNumber = systemAttributes[.systemFileNumber] as? NSNumber {
    print("System File Number: \(fileSystemFileNumber)")
}

Так что, возможно, это может быть короткий путь к поиску маунтов.

Другие вопросы по тегам