在Swift中获取文件大小

Gra*_*lex 55 ios swift

我尝试了几种方法来获取文件大小,但始终为零.

let path = NSBundle.mainBundle().pathForResource("movie", ofType: "mov")
let attr = NSFileManager.defaultManager().attributesOfFileSystemForPath(path!, error: nil)
if let attr = attr {
    let size: AnyObject? = attr[NSFileSize]
    println("File size = \(size)")
}
Run Code Online (Sandbox Code Playgroud)

我进入日志: File size = nil

Duy*_*Hoa 114

在你的attr上使用attributesOfItemAtPath而不是attributesOfFileSystemForPath+ call .fileSize().

var filePath: NSString = "your path here"
var fileSize : UInt64
var attr:NSDictionary? = NSFileManager.defaultManager().attributesOfItemAtPath(filePath, error: nil)
if let _attr = attr {
    fileSize = _attr.fileSize();
}
Run Code Online (Sandbox Code Playgroud)

在Swift 2.0中,我们使用do try catch模式,如下所示:

let filePath = "your path here"
var fileSize : UInt64 = 0

do {
    let attr : NSDictionary? = try NSFileManager.defaultManager().attributesOfItemAtPath(filePath)

    if let _attr = attr {
        fileSize = _attr.fileSize();
    }
} catch {
    print("Error: \(error)")
}
Run Code Online (Sandbox Code Playgroud)

在Swift 3.x/4.0中:

let filePath = "your path here"
var fileSize : UInt64

do {
    //return [FileAttributeKey : Any]
    let attr = try FileManager.default.attributesOfItem(atPath: filePath)
    fileSize = attr[FileAttributeKey.size] as! UInt64

    //if you convert to NSDictionary, you can get file size old way as well.
    let dict = attr as NSDictionary
    fileSize = dict.fileSize()
} catch {
    print("Error: \(error)")
}
Run Code Online (Sandbox Code Playgroud)

  • 是不是只有我认为快速2只是让事情变得更糟糕*.我非常满意&错误.try-catch不是表达式很糟糕. (2认同)
  • 您始终可以使用“尝试?”并获得可选的返回。 (2认同)
  • @BrandonA 以字节为单位 (2认同)

use*_*529 20

Swift4:URL扩展,可轻松访问文件属性

延期:

extension URL {
    var attributes: [FileAttributeKey : Any]? {
        do {
            return try FileManager.default.attributesOfItem(atPath: path)
        } catch let error as NSError {
            print("FileAttribute error: \(error)")
        }
        return nil
    }

    var fileSize: UInt64 {
        return attributes?[.size] as? UInt64 ?? UInt64(0)
    }

    var fileSizeString: String {
        return ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file)
    }

    var creationDate: Date? {
        return attributes?[.creationDate] as? Date
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let fileUrl: URL
print("file size = \(fileUrl.fileSize), \(fileUrl.fileSizeString)")
Run Code Online (Sandbox Code Playgroud)

  • `URL` 直接使用 `resourceValues(forKeys`. (2认同)

Jer*_*ome 16

SWIFT 3来自@ Hoa的回答,加上一个函数让UInt64成为可读字符串.

func sizeForLocalFilePath(filePath:String) -> UInt64 {
    do {
        let fileAttributes = try FileManager.default.attributesOfItem(atPath: filePath)
        if let fileSize = fileAttributes[FileAttributeKey.size]  {
            return (fileSize as! NSNumber).uint64Value
        } else {
            print("Failed to get a size attribute from path: \(filePath)")
        }
    } catch {
        print("Failed to get file attributes for local path: \(filePath) with error: \(error)")
    }
    return 0
}
func covertToFileString(with size: UInt64) -> String {
    var convertedValue: Double = Double(size)
    var multiplyFactor = 0
    let tokens = ["bytes", "KB", "MB", "GB", "TB", "PB",  "EB",  "ZB", "YB"]
    while convertedValue > 1024 {
        convertedValue /= 1024
        multiplyFactor += 1
    }
    return String(format: "%4.2f %@", convertedValue, tokens[multiplyFactor])
}
Run Code Online (Sandbox Code Playgroud)

  • 除了covertToFileString 上的错误外,运行良好。将 `while size > 1024` 替换为 `while ConversionValue > 1024` 以避免无限循环 (2认同)

Guy*_*ker 9

以下是Biodave的答案,正确的文件管理器调用

func sizeForLocalFilePath(filePath:String) -> UInt64 {
    do {
        let fileAttributes = try NSFileManager.defaultManager().attributesOfItemAtPath(filePath)
        if let fileSize = fileAttributes[NSFileSize]  {
            return (fileSize as! NSNumber).unsignedLongLongValue
        } else {
            print("Failed to get a size attribute from path: \(filePath)")
        }
    } catch {
        print("Failed to get file attributes for local path: \(filePath) with error: \(error)")
    }
    return 0
}
Run Code Online (Sandbox Code Playgroud)


boh*_*rna 9

Swift 中的 URL 扩展以获取文件大小(如果有)。

public extension URL {

    var fileSize: Int? {
        let value = try? resourceValues(forKeys: [.fileSizeKey])
        return value?.fileSize
    }
}
Run Code Online (Sandbox Code Playgroud)

返回可选 Int 的原因是因为未知文件大小不能被视为具有零大小。


Ahm*_*tfy 8

Swift 4解决方案:此函数返回MB大小。

func sizePerMB(url: URL?) -> Double {
    guard let filePath = url?.path else {
        return 0.0
    }
    do {
        let attribute = try FileManager.default.attributesOfItem(atPath: filePath)
        if let size = attribute[FileAttributeKey.size] as? NSNumber {
            return size.doubleValue / 1000000.0
        }
    } catch {
        print("Error: \(error)")
    }
    return 0.0
}
Run Code Online (Sandbox Code Playgroud)


vad*_*ian 8

在Swift 3+中,您可以直接从URL获取文件大小,(NS)FileManager不需要.并且ByteCountFormatter是显示文件大小的智能方法.

let url = Bundle.main.url(forResource:"movie", withExtension: "mov")!
do {
    let resourceValues = try url.resourceValues(forKeys: [.fileSizeKey])
    let fileSize = resourceValues.fileSize!
    print("File size = " + ByteCountFormatter().string(fromByteCount: Int64(fileSize)))
} catch { print(error) }
Run Code Online (Sandbox Code Playgroud)

实际上你可以从URLSwift 2中获得文件大小,但语法有点麻烦.


小智 6

试试这个.

let MyUrl = NSURL(fileURLWithPath: "*** Custom File Path ***")                  
let fileAttributes = try! NSFileManager.defaultManager().attributesOfItemAtPath(MyUrl.path!)
let fileSizeNumber = fileAttributes[NSFileSize] as! NSNumber
let fileSize = fileSizeNumber.longLongValue
var sizeMB = Double(fileSize / 1024)
sizeMB = Double(sizeMB / 1024)
print(String(format: "%.2f", sizeMB) + " MB")
Run Code Online (Sandbox Code Playgroud)


abd*_*lek 5

这是Swift 4的另外两个不同的实现,一个是详细格式化的,另一个是十进制格式.

一个NumberFomatter:

func fileSize(fromPath path: String) -> String? {
    var size: Any?
    do {
        size = try FileManager.default.attributesOfItem(atPath: path)[FileAttributeKey.size]
    } catch (let error) {
        print("File size error: \(error)")
        return nil
    }
    guard let fileSize = size as? UInt64 else {
        return nil
    }

    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.formatterBehavior = .behavior10_4
    return formatter.string(from: NSNumber(value: fileSize))
}
Run Code Online (Sandbox Code Playgroud)

而另一个是用大小单位定义:

func fileSize(fromPath path: String) -> String? {
    guard let size = try? FileManager.default.attributesOfItem(atPath: path)[FileAttributeKey.size],
        let fileSize = size as? UInt64 else {
        return nil
    }

    // bytes
    if fileSize < 1023 {
        return String(format: "%lu bytes", CUnsignedLong(fileSize))
    }
    // KB
    var floatSize = Float(fileSize / 1024)
    if floatSize < 1023 {
        return String(format: "%.1f KB", floatSize)
    }
    // MB
    floatSize = floatSize / 1024
    if floatSize < 1023 {
        return String(format: "%.1f MB", floatSize)
    }
    // GB
    floatSize = floatSize / 1024
    return String(format: "%.1f GB", floatSize)
}
Run Code Online (Sandbox Code Playgroud)