Reputation: 1397
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:
getResourceValue:forKey:error:
to read NSURLAllocatedFileSizeKey
(same value as NSURLFileSizeKey
while the file is being written).attributesOfItemAtPath:error:
to look at NSFileBusy
(always NO).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
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
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