I am trying to get the size of a directory, as well as it's content on OS X using Swift. So far, I have only been able to get the size of the directory itself, with none of it's content. For most of my directories it generally shows a value of 6,148 bytes but it does varie.
我试图获得一个目录的大小,以及它使用Swift在OS X上的内容。到目前为止,我只能获得目录本身的大小,而不是它的内容。对于我的大多数目录,它通常显示6,148字节的值,但它确实有变化。
I have tried the directorySize() function from the file below but it returned 6,148 bytes as well.
我已经尝试过下面文件中的directorySize()函数,但它也返回了6,148个字节。
I tried the top 2 answers from this question, but was unsure what argument it needed passed Swift to the Objective-C function. I believe it wants a pointer (I am a beginning programmer in learning).
我尝试了这个问题的前两个答案,但不确定它需要什么参数将Swift传递给Objective-C函数。我相信它想要一个指针(我是学习的初级程序员)。
Calculate the size of a folder
计算文件夹的大小
And I could not get the Swift answer from here to work for my purpose either.
而且我无法从这里得到Swift的答案也可以用于我的目的。
How to get the file size given a path?
如何获得给定路径的文件大小?
I am using Xcode 7.0 and running OS X 10.10.5.
我正在使用Xcode 7.0并运行OS X 10.10.5。
3 个解决方案
#1
11
update: Xcode 8.2.1 • Swift 3.0.2
更新: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"
}
If you would like to include all subFolders, hidden files and package descendants you need to use enumeratorAtURL as follow:
如果要包含所有子文件夹,隐藏文件和包后代,则需要使用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"
}
#2
2
Swift 3 version
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
}
#3
2
Swift 3 version here:
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
}
Output value is megabyte. Converted from source: https://gist.github.com/rayfix/66b0a822648c87326645
输出值为兆字节。转自来源:https://gist.github.com/rayfix/66b0a822648c87326645
#1
11
update: Xcode 8.2.1 • Swift 3.0.2
更新: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"
}
If you would like to include all subFolders, hidden files and package descendants you need to use enumeratorAtURL as follow:
如果要包含所有子文件夹,隐藏文件和包后代,则需要使用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"
}
#2
2
Swift 3 version
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
}
#3
2
Swift 3 version here:
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
}
Output value is megabyte. Converted from source: https://gist.github.com/rayfix/66b0a822648c87326645
输出值为兆字节。转自来源:https://gist.github.com/rayfix/66b0a822648c87326645