Как получить размер каталога с Swift на OS X


Я пытаюсь получить размер каталога, а также его содержимое в OS X с помощью Swift. До сих пор мне удавалось получить только размер самого каталога, без его содержимого. Для большинства моих каталогов он обычно показывает значение 6,148 байт, но он меняется.

Я попробовал функцию directorySize() из файла ниже, но она вернула 6148 байт как хорошо.

Https://github.com/amosavian/ExtDownloader/blob/2f7dba2ec1edd07282725ff47080e5e7af7dabea/Utility.swift

Я попробовал 2 лучших ответа из этого вопроса,но не был уверен, какой аргумент он должен был передать Swift в функцию Objective-C. Я считаю, что ему нужен указатель (я начинающий программист в обучении).

Вычислите размер папки

И я не мог получить быстрый ответ отсюда, чтобы работать для моей цели. любой.

Как получить размер файла с заданным путем?

Я использую Xcode 7.0 и запускаю OS X 10.10.5.

3 5

3 ответа:

Обновление: Xcode 8.2.1 * Swift 3.0.2

// get your directory url
let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// check if the url is a directory
if (try? documentsDirectoryURL.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true {
    print("url is a folder url")
    // lets get the folder files
    var folderSize = 0
    (try? FileManager.default.contentsOfDirectory(at: documentsDirectoryURL, includingPropertiesForKeys: nil))?.lazy.forEach {
        folderSize += (try? $0.resourceValues(forKeys: [.totalFileAllocatedSizeKey]))?.totalFileAllocatedSize ?? 0
    }
    // format it using NSByteCountFormatter to display it properly
    let  byteCountFormatter =  ByteCountFormatter()
    byteCountFormatter.allowedUnits = .useBytes
    byteCountFormatter.countStyle = .file
    let folderSizeToDisplay = byteCountFormatter.string(for: folderSize) ?? ""
    print(folderSizeToDisplay)  // "X,XXX,XXX bytes"
}

Если вы хотите включить все вложенные папки, скрытые файлы и потомки пакетов, вам нужно использовать enumeratorAtURL следующим образом:

// get your directory url
let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// check if the url is a directory
if (try? documentsDirectoryURL.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true {
    var folderSize = 0
    (FileManager.default.enumerator(at: documentsDirectoryURL, includingPropertiesForKeys: nil)?.allObjects as? [URL])?.lazy.forEach {
        folderSize += (try? $0.resourceValues(forKeys: [.totalFileAllocatedSizeKey]))?.totalFileAllocatedSize ?? 0
    }
    let  byteCountFormatter =  ByteCountFormatter()
    byteCountFormatter.allowedUnits = .useBytes
    byteCountFormatter.countStyle = .file
    let sizeToDisplay = byteCountFormatter.string(for: folderSize) ?? ""
    print(sizeToDisplay)  // "X,XXX,XXX bytes"
}

Swift 3 версия

private func sizeToPrettyString(size: UInt64) -> String {

    let byteCountFormatter = ByteCountFormatter()
    byteCountFormatter.allowedUnits = .useMB
    byteCountFormatter.countStyle = .file
    let folderSizeToDisplay = byteCountFormatter.string(fromByteCount: Int64(size))

    return folderSizeToDisplay

}

Swift 3 версия здесь:

 func findSize(path: String) throws -> UInt64 {

    let fullPath = (path as NSString).expandingTildeInPath
    let fileAttributes: NSDictionary = try FileManager.default.attributesOfItem(atPath: fullPath) as NSDictionary

    if fileAttributes.fileType() == "NSFileTypeRegular" {
        return fileAttributes.fileSize()
    }

    let url = NSURL(fileURLWithPath: fullPath)
    guard let directoryEnumerator = FileManager.default.enumerator(at: url as URL, includingPropertiesForKeys: [URLResourceKey.fileSizeKey], options: [.skipsHiddenFiles], errorHandler: nil) else { throw FileErrors.BadEnumeration }

    var total: UInt64 = 0

    for (index, object) in directoryEnumerator.enumerated() {
        guard let fileURL = object as? NSURL else { throw FileErrors.BadResource }
        var fileSizeResource: AnyObject?
        try fileURL.getResourceValue(&fileSizeResource, forKey: URLResourceKey.fileSizeKey)
        guard let fileSize = fileSizeResource as? NSNumber else { continue }
        total += fileSize.uint64Value
        if index % 1000 == 0 {
            print(".", terminator: "")
        }
    }

    if total < 1048576 {
        total = 1
    }
    else
    {
        total = UInt64(total / 1048576)
    }

    return total
}

enum FileErrors : ErrorType {
    case BadEnumeration
    case BadResource
}

Выходное значение-мегабайт. Преобразовано из источника: https://gist.github.com/rayfix/66b0a822648c87326645