Josh at The Nerdery
Josh at The Nerdery

Reputation: 1397

(OS X) Determine if file is being written to?

My app is monitoring a "hot" folder somewhere on the local filesystem for newly added files to push to a network location. I'm running into a problem when very large files are being written into the hot folder: the file system event notifying me of changes in the hot folder will fire well before the file completes writing. When my app tries to upload the file, it mis-reads the file size as the current number of copied bytes, not the eventual total number of bytes.

Things I've tried:

I can't seem to find any mechanism short of repeatedly polling a file for its size to determine if the file is finished copying and can be uploaded.

Upvotes: 2

Views: 1170

Answers (2)

Ken Thomases
Ken Thomases

Reputation: 90671

There aren't great ways to do this.

If you can be certain that the writer is using NSFileCoordinator, then you can also use that to coordinate your access to the file.

Likewise, if you're sure that the writer has opted in to advisory locking, you could try to open the file for shared access by calling open() with the O_SHLOCK and O_NONBLOCK flags. If you succeed, then there are no other descriptors open for exclusive access. You can either use the file descriptor you've got or close it and then use some other API to access the file.

However, if you can't be sure of any of those, then your best bet may be to set a timer to repeatedly check the file's metadata (size, date modified, etc.). Only when you see that it has stopped changing over a reasonable time interval (2 seconds, maybe) would you attempt to access it (and cancel the timer).

You might want to do all three. Wait for the file's metadata to settle down, then use a NSFileCoordinator to read from the file. When it calls your reader block, use open() with O_SHLOCK | O_NONBLOCK to make sure there are no other processes which have exclusive access to it.

Upvotes: 5

uchuugaka
uchuugaka

Reputation: 12782

You need some form of coordinated file locking.

fcntl() and flock() are common functions for this. Read up on it first. Then see what options you have. If you can control the code base of those other processes, all the better.

The problem with really large files is that what's changed or changing inside them is opaque and isn't always at the end. Good processes should generally be doing atomic writes. (Write to a temp file then swap it out) but if these files are actually databases then you will want to look at using the db's server app for this sort of thing.

If the files are wrappers containing other files then it gets extra messy as those contents might have dependencies on one another to be in a usable state.

Upvotes: 0

Related Questions