SwiftUI获取文件大小/占用空间
SwiftUI获取文件大小/占用空间

SwiftUI获取文件大小/占用空间

在SwiftUI中,可以通过两种方法获取文件的大小。

以图片文件为例,首先获取图片的URL,然后计算图像的大小。

fileURL为图片文件的URL路径。

1、获取Finder的文件大小

let resourceValues = try? fileURL.resourceValues(forKeys: [.totalFileAllocatedSizeKey])
let DiskSize = resourceValues?.totalFileAllocatedSize ?? 0

2、获取文件的实际大小

let attributes = try? FileManager.default.attributesOfItem(atPath: fileURL.path)[.size] as? Int

两者的区别

获取的Finder文件通常要大于文件的实际大小:

macOS显示的大小:90112
获取的文件实际大小:86523

这是因为Finder通常显示的是 .totalFileAllocatedSize,因为文件系统最小分配单位通常是 4KB、8KB 等,实际占用会比原始字节大。

因此,如果想要显示文件的原始字节,可以实现 .fileSize,显示Finder的大小,则使用 .totalFileAllocatedSizeKey。

macOS和自己计算的文件大小不同

以图片文件为例,在macOS上显示107 KB,自己计算的大小为96 KB,这里存在三个原因:

1、macOS 使用十进制单位(即 1000),不是二进制单位(1024)

1 KB,在二进制中显示1024 B,十进制中显示1000 B。

1 MB,在二进制中显示1024 KB = 1048576 B,十进制中显示1000 KB = 1,000,000 B。

macOS 的 Finder、系统文件信息等默认采用十进制(即 1KB = 1000 字节)。

2、使用rounded计算

在计算文件大小时,不要使用Int计算:

let sizeNum = size / pow(num,1.0)  // OK
return "\(Int(sizeNum)) KB"        // 这里向下取整了

因为,Int总会向下取整,因此应该使用rounded()替代Int:

let sizeNum = (size / 1000.0).rounded()  // 四舍五入为最近整数
return "\(Int(sizeNum)) KB"

3、没有获取Finder显示的磁盘占用大小

// 获取 Finder 上的大小
let resourceValues = try? fileURL.resourceValues(forKeys: [.totalFileAllocatedSizeKey])
let DiskSize = resourceValues?.totalFileAllocatedSize ?? 0
print("DiskSize:\(DiskSize)")

// 获取文件的实际大小
let attributes = try? FileManager.default.attributesOfItem(atPath: fileURL.path)[.size] as? Int

这两种方法,同一个照片,Finder获取的图像大小为90112字节,FileManager获取的大小是86523字节。

如果想要显示Finder的字节大小,应该用第一种方法。

计算文件大小代码

func TranslateSize(fileSize: Int) -> String {
    let num = 1000.0
    let size = Double(fileSize)
    if size < num {
        return "\(size) B"
    } else if size < pow(num,2.0) {
        let sizeNum = size / pow(num,1.0)
        return "\(ceil(sizeNum.rounded())) KB"
    } else if size < pow(num,3.0) {
        let sizeNum = size / pow(num,2.0)
        return "\(String(format:"%.2f",sizeNum)) MB"
    } else if size < pow(num,4.0) {
        let sizeNum = size / pow(num,3.0)
        return "\(String(format:"%.2f",sizeNum)) GB"
    } else if size < pow(num,5.0) {
        let sizeNum = size / pow(num,4.0)
        return "\(String(format:"%.2f",sizeNum)) TB"
    } else {
        let sizeNum = num / pow(num,4.0)
        return "\(String(format:"%.2f",sizeNum)) TB"
    }
}
   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注