How to Get Directory Size with Swift on Os X

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



Leave a reply



Submit