How macOS tracks your files: inside the inode

Some Mac apps track your documents no matter where you care to move them on a volume, or what name you wish to give them. Others can’t cope, and the moment anything changes about the document (apart from its contents), you have to open them afresh. Why the difference?

It comes down to a neat Unix feature in macOS file management – the inode.

Associated with every file and folder is information about that item: its owner and group owner, permissions, dates of creation and modification, size, and so on. These are stored in data structures known as inodes. Within those, every item has a unique identity number which remains fixed, no matter what it is named, or where it might go on that particular volume: the inode serial number or ID, sometimes simply referred to as the inode. (You may also hear them referred to as vnodes, a term from BSD systems.)

When an app opens or saves a document, it does so using its path and file name, the URL. The difference between apps comes with how those documents are remembered, most obviously for the Open Recent command. Better apps remember their documents using their inode serial numbers, so when they want to open them again, they ask macOS for the file with that serial number. Weaker apps remember their documents by their URLs, so if any part of that changes, they can’t find the document to re-open it.

You can view the inode data for a file or folder in Terminal, using a command of the form
stat filename
where filename is the path and name of the file or folder. This might return something like
16777224 347940266 -rw-r--r-- 1 hoakley staff 0 1086 "Mar 1 23:12:43 2018" "Jan 6 07:00:28 2018" "Feb 27 23:45:02 2018" "Sep 4 14:00:12 2017" 4096 16 0x40 testLetter.tex
which gives the inode number of that item as the second large integer, here 347940266.

You can also discover inode numbers using the -i option for the ls command, which lists inode numbers against each item.

To make it even easier to view inode numbers and other data, I have added this feature to version 1.0b2 of Precize, now available from here: precize10b2 and from the Downloads page above.

precize06

This lists all the available inode data, using Apple’s naming system for the different values. Typically, those include:

  • NSFileOwnerAccountName, the short user name of the owner
  • NSFilePosixPermissions, the item’s POSIX permissions, given as an integer
  • NSFileSystemNumber, the inode number of the volume containing the item
  • NSFileReferenceCount, the number of hard links to the item
  • NSFileSystemFileNumber, the item’s inode number
  • NSFileCreationDate, the datestamp of the item’s creation
  • NSFileHFSTypeCode, where 0 is a regular file
  • NSFileType, the type of item, e.g. NSFileTypeRegular
  • NSFileExtendedAttributes, a list of any extended attributes (xattrs)
  • NSFileGroupOwnerAccountName, the name of the group owner
  • NSFileGroupOwnerAccountID, the ID of the group owner
  • NSFileHFSCreatorCode, typically 0
  • NSFileModificationDate, the datestamp of last modification of the item
  • NSFileSize, the size of the file’s data fork, excluding any extended attributes
  • NSFileExtensionHidden, if 1, then the extension is hidden
  • NSFileOwnerAccountID, the ID of the owner.

Thanks to @schackspelar, who suggests that the hidden file named .file probably contains the current upper limit of inode numbers on that volume.