How large is that file?
At first sight, this might seem a simple question to answer. Allow me to demonstrate that it’s more complex, has changed over time, and still hasn’t been resolved.
Before 1984
Although there were exceptions, before the Mac most file systems that we were likely to encounter were simple. Each file consisted of stored data, together with a small entry in the file system’s metadata containing information such as the file’s name and its time and date of creation. By convention, as that’s not stored with the file’s data, that isn’t included in its size.
The only complication here was that storage is divided up into blocks, so in addition to the file’s actual size, we’d also want to know the total size taken by the storage blocks it used, as any given block couldn’t be shared between files, a figure often known as size on disk, and dependent on the size of those blocks. If the block size is 4,096 bytes, then any file whose data was equal to or smaller than that had a size on disk of 4,096 bytes, 4 KiB or 4.096 KB. (There are 1,000 bytes in a KB, but 1,024 bytes in a KiB.)
Classic Mac OS
One of the many innovations in the first Mac was its file system MFS, in which every file has two forks, one the traditional data fork, the other a resource fork for storing structured blobs of data termed resources. As MFS was replaced by HFS and eventually HFS+, those resource forks continued.
Resource forks often reached considerable sizes, and although they are stored separately from data forks in HFS+, Apple usually gave the sizes of the two forks, as shown in this dialog, where the size of the resource fork is 117,836 bytes, almost as large as the file’s 144,788 bytes of data. Information about the size of that file’s entry in the file system data, its attributes, wasn’t given, though.
HFS+ in Mac OS X
In the early years of Mac OS X, there was controversy as to whether it should continue supporting the use of resource forks, and most of their uses were replaced by flattened data files arranged in bundles. Nevertheless, in Mac OS X 10.4, HFS+ became multi-forked with what were dubbed extended attributes or xattrs, one type being com.apple.ResourceFork, the classic resource fork. However, the practice of giving separate sizes for the data fork and other forks died.
APFS
When APFS was released in 2017, it changed the way in which xattrs are stored, as explained here. Now, each file can consist of:
- file system attributes, stored in the file system metadata structures;
- small xattrs of up to 3,804 bytes, stored separately from its attributes, but in file system metadata;
- large xattrs over 3,804 bytes, typically including any com.apple.ResourceFork, stored as data streams with separate records;
- data, stored in storage blocks as set out in their file extents.
As demonstrated using crafted files, initially the Finder ignored items 1-3 in stating file size, and just gave that of 4, the data, although it could instead still have been including resource forks, of course.
The size of this text file is given as 391 bytes in the Finder’s Get Info in High Sierra, but as you’ll see below it contains over 90,000 bytes of extended attributes that figure simply ignores.
macOS Sequoia
Here are the sizes given for another of my specially crafted demonstration files, for APFS in macOS 15.6.1 Sequoia.
According to the Finder’s Get Info dialog, this file contains 263,195 bytes and occupies 266 KB on disk. On an SSD with the standard 4 KiB block size, that should be 65 blocks, or 266,240 bytes, as given correctly. There’s something amiss with that file, though, as it claims to be a Zip archive but has an image thumbnail.
Listing its xattrs using xattred reveals no less than 14, including two of 80 KB each. xattred claims it has a data fork size of 183,136 bytes and 161,406 bytes in xattrs, making a total size of 344,542 bytes, which is nowhere near that given by the Finder. (It’s the com.apple.ResourceFork xattr, a classic resource fork, that contains the image thumbnail displayed by QuickLook instead of the normal Zip file icon.)
To discover how the Finder arrives at a size of 263,195 bytes, we need to subtract the data size from that, making 80,059 bytes, the size of the file’s resource fork or com.apple.ResourceFork xattr. So, without being explicit about forks, it’s behaving the same as in Classic Mac OS. You might find that puzzling, given that there’s another xattr of the same size that it’s ignoring, and a dozen more that don’t get a look-in. As the use of com.apple.ResourceFork xattrs has long been discouraged if not deprecated, isn’t that a strange behaviour? The more so when modern xattrs that Apple has introduced relatively recently, such as com.apple.quarantine, com.apple.macl and com.apple.provenance, are ignored.
The deeper you look into this, the more puzzling it becomes. Here are the same file’s figures as shown in Precize.
Sizes are given a few lines down, from two sources, URL Keys and the file system (FileManager), and they also differ. There’s a list of xattrs given at the foot of this window, but that only gives 12 and ignores com.apple.ResourceFork and com.apple.FinderInfo.
In the macOS API, code can obtain values for file sizes from its URL. Two keys are available, fileSizeKey and totalFileSizeKey. The first gives the data size, and the second is the same ‘total’ as that shown by the Finder, i.e. data + com.apple.ResourceFork xattr, but excluding all other xattrs. Apple’s documentation explains those as:
fileSize
is “the total file size, in bytes”totalFileSize
is “the total displayable size of the file, in bytes. The allocated size in bytes may include space used by metadata.”
FileManager also gives the data size in its FileAttributeKey.size, but doesn’t give any for xattrs, even com.apple.ResourceFork. The size of the Metadata shown for the File system is instead calculated by totalling the individual sizes of all its xattrs, including com.apple.ResourceFork and com.apple.FinderInfo.
This may appear to be nit-picking, but data sizes are given to the exact number of bytes, and the size on disk for non-sparse files should always be within 4,095 bytes of the data size. Yet accounting for xattrs remains rooted in Classic Mac OS from 25 years ago and still pretends that xattrs either don’t exist, or don’t take any space.