How can I determine whether a certain path points to a hidden file/folder?
NSString *file = @"/my/file/some.where";
BOOL fileIsHidden = // <-- what do I do here?
I know that hidden files are prefixed by a period. This is not the only criteria for a file to be hidden. I've read somewhere that there's a .hidden file that also configures what files are hidden.
Is there a Cocoa/Carbon way to find this out easily without rewriting all this logic and gathering information from various sources?
EDIT: the kLSItemInfoIsInvisible check seems to work for some files. It doesn't seem to hide:
/dev /etc /tmp /var
All these are hidden by Finder by default.
As far as I know, hidden files on OS X are determined by either the filename being prefixed with a period or by a special "invisible" bit that is tracked by the Finder.
A few years back, I had to write something that toggled the visibility of a given file, and I found it was actually a lot more complicated than I expected. The crux of it was obtaining a Finder info (
FInfo
) record for the file and checking if thekIsInvisible
bit was set. Here's the method I wrote for toggling file visibility—I think a lot of it is relevant to your task at hand, although you'll obviously have to tweak it a bit.Here's Apple's documentation on the Finder Interface, if you want more information. Hope this helps.
As the poster pointed out, it doesn't seem to work on /etc and /var and what not, so I modified the method.
It now takes a "isFile" boolean, YES means its a file, NO means a directory
It seems to work on everything now!
I think the point is that the Finder is the frontend towards the user of the filesystem tree(s). You want to ask the Finder if he thinks that a file is hidden or not, so you need an API to do that.
It seems that LSCopyItemInfoForURL does the work, as shown in the other answers. This post is very useful:
I'm not copying it all, it's long but well written.
Philosophical bit first:
No file is actually hidden. The Finder maintains its own internal data to determine if a file should be displayed in a directory listing or not; and this information may be shared with the other applications on the system.
Still, unless you are implementing a file system browser, the relevant determinations are usually transparently taken care of (no pun intended) by the internal workings of
NSOpenPanel
and friends.If you are accessing a file programatically, and you maintain some semblance of ownership over the same file, or you are not displaying the file (or not) in the UI, it really doesn't matter if Finder considers it hidden or not.
As for the technical bit; since any application is able (through the aforementioned and venerable
NSOpenPanel
) to access this information, it's probably available somewhere; but as has been pointed out, this requires a rather circuitous little delve into CoreFoundation and LaunchServices.The real issue is probably wether you need to know.
From http://forums.macosxhints.com/archive/index.php/t-22641.html:
Update
Aha! /etc, /tmp, and /var are all invisible because they're actually symlinks to /private/etc, /private/tmp, and /private/var. If you tell Finder to directly visit /private (using the Go To Folder menu item), you'll see that they show up just fine. (Thanks to @IlDan for the tip)
I'm not sure what the best way to deal with this is; it only matters if you have a visible symlink to a file inside a hidden folder. You could probably get away with just manually excluding symlinks that go into /private, but if now, you might have to check the hidden status of every folder on the way up the path.