I would like to get notified, when a specific file gets opened or closed by another application.
I tried different things like DispatchSource
, FSEvents
and kqueue
, but nothing worked. The only option so far is searching for all process ids, that accesses the file with proc_listpidspath
(or with the command line tool lsof
). Unfortunately I need to use a Timer
for this. But checking i. e. every second will need a lot of CPU, so I'm curious, if there is a built in notification in macOS?
Let’s start with a link to the Swift Forums thread, which has more context.
On Swift Forums you wrote:
I am developing a server client application with a document management system. When a client wants to access a file, the file is sent from the server to the client and so that no other clients can edit the file, it's getting locked for everbody else. If the client, where the file is opened, now save his changes and when he closes the file, the new file should automatically be uploaded to the server and then be unlocked.
That’s not gonna work, at least not at this level and in the general case.
And in response to tera’s point about apps not keeping files open you wrote:
What do you mean with "many apps don't keep files open during editing"?
Consider this:
-
Find or create an RTF file somewhere on your Mac.
-
Open it in TextEdit.
-
Check to see if TextEdit has it open:
% lsof -p `pgrep TextEdit` | grep rtf %
Spoiler alert: It does not.
Would be interesting, which apps do this
Many apps. Even traditional Unix-y apps don’t necessarily keep the file open. For example, if you repeat the above test with vi
you’ll find that it has .test.rtf.swp
open, but not test.rtf
.
(and especially why).
Because they don’t need to keep the file open. Their model of the file is in memory.
Or because they do all their work in a secondary file and only commit to the real file when you save.
This comes back to another point you raised on DevForums:
the FileEventHandler doesn't contain the
.write
, when my file is saved.
Right. That’s because most apps use a safe-save mechanism, where they write to a temporary and then replace the original file with that. In that case you won’t see a write event for the file, but a write event for the parent directory.
Coming back to the big picture, your approach is not going to work reliably. This isn’t due to macOS API limitations — although there are plenty of those (-: — but because you’re working at the wrong level. I see this quite a bit in my job: Folks trying to infer high-level semantics (in this case document open and close) from low-level operations (file system activity). I even have a post that discusses the problem in general: Inferring High-Level Semantics from Low-Level Operations.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"