It’s commonly claimed that macOS relies entirely on filename extensions to determine a file’s type, and that’s largely true, and easy to demonstrate. Duplicate a PDF document, and confirm that double-clicking it opens it in your default PDF editor. If you’ve got a current version of my free utility SpotTest, open its Drop Window and drop that file onto it.
SpotTest then shows three separate reports on that file:
- file(1) at the top reports it’s a PDF document, giving its version and length.
- mdimport at the left reports it’s of UTI type com.adobe.pdf and was imported using PDF.mdimporter.
- mdls on the right reports it has kMDItemContentType of com.adobe.pdf.
Now change that file’s extension to txt, and drop it onto the Drop Window again:
- file(1) at the top still reports it’s a PDF document, giving its version and length.
- mdimport at the left reports it’s now of UTI type public.plain-text and was imported using RichText.mdimporter.
- mdls on the right also reports it has kMDItemContentType of public.plain-text.
Sure enough, this has also persuaded QuickLook that it’s really text after all, and its contents are shown in thumbnail and preview as a load of jumbled characters, and double-clicking it opens those in TextEdit.
Now try a similar trick with an image file such as a JPEG. With the correct extension, SpotTest should display:
- file(1) at the top reports it contains JPEG image data, giving details of its JFIF standard and more.
- mdimport at the left is blank because of a bug in the command tool, which crashes when used on images.
- mdls on the right reports it has kMDItemContentType of public.jpeg.
Change its extension to another type of image such as PNG, and that becomes:
- file(1) at the top still reports it contains JPEG image data, giving details of the JFIF standard and more.
- mdimport at the left remains blank because of the bug.
- mdls on the right now reports it has kMDItemContentType of public.png.
But, remarkably, QuickLook still manages to display its thumbnail and preview correctly, and LaunchServices opens it correctly in Preview and GraphicConverter.
So there’s more to a file’s type than just its UTI as determined by its filename extension, as it depends on which subsystem in macOS is checking it.
LaunchServices, responsible for mapping file types to apps, is content to go with whatever the filename extension says, as that determines its UTI. QuickLook and Spotlight indexing appear to start by looking at the UTI to allocate the file to an appropriate qlgenerator or mdimporter, but that doesn’t trust the UTI to get the file type right, so they do that using something similar to file(1), which appropriately relies on magic and not UTIs. magic is the method and database used by file(1) when it ‘sniffs’ the data in a file, to work out what type it is without trusting the filename extension or UTI.
In those examples, file(1) is more reliable and precise than relying on the UTI, but it does have its drawbacks. Create a text file containing just the words
Draw upon the minds of great men for your inspiration.
Save it with a filename and a standard txt extension, and drop that onto DropTest’s Drop Window. This is what I see:
- file(1) at the top reports it contains RISC OS Draw file data.
- mdimport at the left reports it’s of UTI type public.plain-text and was imported using RichText.mdimporter, but look at the foot and you won’t see any kMDItemTextContent reported, as Spotlight hasn’t indexed its contents.
- mdls on the right reports it has kMDItemContentType of public.plain-text, but there’s no _kMDItemPrimaryTextEmbedding for indexed text content.
The end result is that some plain text files don’t get indexed by Spotlight.
So what does determine a file’s type in macOS? It all depends.
