How To Get Directory Size With Swift On OS X
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)
}
Get file size in Swift
Use attributesOfItemAtPath
instead of attributesOfFileSystemForPath
+ call .fileSize() on your attr.
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();
}
In Swift 2.0, we use do try catch pattern, like this:
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)")
}
In 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)")
}
How to get Total/Available/Used space of a USB drive in MacOS - Swift?
You can use FileManager's mountedVolumeURLs
method to get all mounted volumes and get the volumeAvailableCapacityForImportantUsage
resource key/value from it:
extension FileManager {
static var mountedVolumes: [URL] {
(FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil) ?? []).filter({$0.path.hasPrefix("/Volumes/")})
}
}
extension URL {
var volumeTotalCapacity: Int? {
(try? resourceValues(forKeys: [.volumeTotalCapacityKey]))?.volumeTotalCapacity
}
var volumeAvailableCapacityForImportantUsage: Int64? {
(try? resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey]))?.volumeAvailableCapacityForImportantUsage
}
var name: String? {
(try? resourceValues(forKeys: [.nameKey]))?.name
}
}
Usage:
for url in FileManager.mountedVolumes {
print(url.name ?? "Untitled")
print("Capacity:", url.volumeTotalCapacity ?? "nil")
print("Available:", url.volumeAvailableCapacityForImportantUsage ?? "nil")
print("Used:", (try? url.sizeOnDisk()) ?? "nil") // check the other link below
}
For a 16GB USB drive with BigSur installer the code above will print
Install macOS Big Sur
Capacity: 15180193792
Available: 2232998976
Used: 12.93 GB on disk
To get the used space of a volume "sizeOnDisk" you can check this post
How to get Size and free space of a directory in cocoa?
You can calculate the size of a directory using this particular method, the fastest, using Carbon, instead of NSEnumerator :
here
To calculate free space, you could use that method. Make sure you enter the full path of the volume :
NSDictionary* fileAttributes = [[NSFileManager defaultManager] fileSystemAttributesAtPath:folder];
unsigned long long size = [[fileAttributes objectForKey:NSFileSystemFreeSize] longLongValue];
Where size is what you're looking for.
How do you find how much disk space is left in Cocoa?
Use -[NSFileManager attributesOfFileSystemForPath:error:]
Related Topics
Lesser Than or Greater Than in Swift Switch Statement
Swift Write/Save/Move a Document File to Icloud Drive
Sort Array by Calculated Distance in Swift
When Did 'Guard Let Foo = Foo' Become Legal
Iboutlet of Another View Controller Is Nil
How to Properly Use Queryorderedbyvalue
How to Satisfy Swift Protocol and Add Defaulted Arguments
Embedding Videos in a Tableview Cell
Firebase Converting Snapshot Value to Objects
How to Init a Uibutton Subclass
Init(Start:End:)' Is Deprecated: It Will Be Removed in Swift 3. Use the '..<' Operator
How to Set Collection View's Cell Size via the Auto Layout
Concatenate Two Audio Files in Swift and Play Them
Ambiguous Reference to Member 'Tableview'
Returning a Value from a Function with Alamofire and Swiftyjson
Swift Custom Context Menu Previewprovider Can Not Click Any View Inside(Using Tapgesture)
How to Set the Legacy Swift Versions for Each Pod in Podfile