How to get file size using FileManager + formatting
Learn how to get file size URL and also how to format it to human-readable string by special formatter.
Published: June 2, 2020 Sponsored See booksIf you need to get file size programmatically in Swift using the file's URL then it is just a matter of a few lines of code. Let's see how. All we need is an URL for the file in question.
Getting file size with FileManager
We are going to use method attributesOfItem
available on the FileManager
. As the naming suggests this will return attributes for item. In our case a file. We need to supply a path to the file which we can get from the URL.
if let fileAttributes = try? FileManager.default.attributesOfItem(atPath: fileURL.path) {
}
This method can throw so we are using try?
to safely get the attributes or nil
in case of an issue. In this case that would most likely be incorrect path or for some reason unreadable file.
fileAttributes
is a dictionary and we can get size like so:
if let bytes = fileAttributes[.size] as? Int64 {
}
The whole thing is in bytes meaning it is not very human-readable number.
Extension
We can also create handy extension to abstract away all this code. Feel free to use it in your project 🙂
extension FileManager {
func sizeOfFile(atPath path: String) -> Int64? {
guard let attrs = try? attributesOfItem(atPath: path) else {
return nil
}
return attrs[.size] as? Int64
}
}
It depends whether you need to use file size internally (to maybe estimate upload time etc) or if you want to present the result to the user.
In the latter case do not display number of bytes but instead convert it to readable number.
Displaying readable size with ByteCountFormatter
Swift has really cool and useful class called ByteCountFormatter
which can format byte count to readable string.
Let's use it to format our file size.
ByteCountFormatter usage
let bcf = ByteCountFormatter()
bcf.allowedUnits = [.useMB]
bcf.countStyle = .file
let string = bcf.string(fromByteCount: bytes)
We first create instance, then set allowedUnits
in this case to only megabytes because we are expecting files bigger than 1 MB and smaller than 1 GB and set countStyle
to .file
.
Then it is just a matter of getting the resulting string. ByteCountFormatter
will automatically append unit (in this case "MB") so we don't have to do any post-formatting. 👏
The result will be something like "24,4 MB" with either "," or "." as a separator depending on the user's locale settings.
For frequent usage I would recommend creating something like a static instance to avoid creating instances over and over again and have centralized configuration.
private let fileByteCountFormatter: ByteCountFormatter = {
let bcf = ByteCountFormatter()
bcf.allowedUnits = [.useMB]
bcf.countStyle = .file
return bcf
}()
And that is it! For more options you can check the official documentation.
Thanks for reading!
Uses: Xcode 12 & Swift 5.3