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 vary.
I have tried the directorySize() function from the file below but it returned 6,148 bytes as well.
And I could not get the Swift answer from here to work for my purpose either.
How to get the file size given a path?
I am using Xcode 7.0 and running OS X 10.10.5.
update: Xcode 11.4.1 • Swift 5.2
extension URL {
/// check if the URL is a directory and if it is reachable
func isDirectoryAndReachable() throws -> Bool {
guard try resourceValues(forKeys: [.isDirectoryKey]).isDirectory == true else {
return false
}
return try checkResourceIsReachable()
}
/// returns total allocated size of a the directory including its subFolders or not
func directoryTotalAllocatedSize(includingSubfolders: Bool = false) throws -> Int? {
guard try isDirectoryAndReachable() else { return nil }
if includingSubfolders {
guard
let urls = FileManager.default.enumerator(at: self, includingPropertiesForKeys: nil)?.allObjects as? [URL] else { return nil }
return try urls.lazy.reduce(0) {
(try $1.resourceValues(forKeys: [.totalFileAllocatedSizeKey]).totalFileAllocatedSize ?? 0) + $0
}
}
return try FileManager.default.contentsOfDirectory(at: self, includingPropertiesForKeys: nil).lazy.reduce(0) {
(try $1.resourceValues(forKeys: [.totalFileAllocatedSizeKey])
.totalFileAllocatedSize ?? 0) + $0
}
}
/// returns the directory total size on disk
func sizeOnDisk() throws -> String? {
guard let size = try directoryTotalAllocatedSize(includingSubfolders: true) else { return nil }
URL.byteCountFormatter.countStyle = .file
guard let byteCount = URL.byteCountFormatter.string(for: size) else { return nil}
return byteCount + " on disk"
}
private static let byteCountFormatter = ByteCountFormatter()
}
usage:
do {
let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if let sizeOnDisk = try documentDirectory.sizeOnDisk() {
print("Size:", sizeOnDisk) // Size: 3.15 GB on disk
}
} catch {
print(error)
}