When you are writing files out to disk, and you want to ensure that the operation completes properly, you should do something called a "safe copy." What this prevents are corrupt files when things like power outages happen. Let's say your application is busy saving a 100 MB file out to disk, and the user accidentally kicks the power cord on the desktop. If you're not doing a safe copy, then the file's state is essentially corrupt because it wasn't able to write all of the data out. However, by doing a safe copy, what happens is that the file is *not* corrupted because it was never really saved out in the first place.
The way this happens (from a high-level overview) is that you do all of your writing to a temporary file, and once you've completed writing, you replace the true saved copy with the temporary one. If the replacement process is interrupted, then the OS will essentially cancel the file operation, thereby leaving the user's true copy alone. By doing this, you prevent data corruption with half-saved files.
On the Mac, there's the FSExchangeObjects API which is available to do a file replacement. However, I'm not going to cover how to use that because I'm a bad, bad person. ;-) Plus, I am pretty sure that others have already covered this topic for the Mac. Instead, I'm going to show you how to do this using the ReplaceFile API on Windows. This API exists on Windows 2000 and up and does everything you would expect it to do. It copies over file attributes, access rights, creation dates... the whole nine yards. It's also trivial to use.
[rbcode]
Soft Declare Function ReplaceFileW Lib "Kernel32" ( destination as WString, source as WString, _
backup as Integer, flags as Integer, reserved1 as Integer, reserved2 as Integer ) as Integer
if System.IsFunctionAvailable( "ReplaceFileW", "Kernel32" ) then
Const REPLACEFILE_WRITE_THROUGH = &h1
if ReplaceFileW( theDestination.AbsolutePath, theSource.AbsolutePath, 0, _
REPLACEFILE_WRITE_THROUGH, 0, 0 ) <> 0 then
MsgBox "You win a pony"
else
MsgBox "Your pony just died of typhoid."
end if
end if[/rbcode]
It's just that simple. The first parameter is the destination file which is being saved. The second parameter is the source file which you wrote out to the temp directory. The third parameter is a backup file if you want to save a backup of the file being replaced. The flags we pass in promise that this function will not return until everything has been flushed to the disk. The final two parameters are both reserved, and so they're 0.
The only caveat to using this function is that all three file paths must reside on the same volume. So if you are saving to the temp directory of C: and you are replacing to a SMB mount on Z:, this function will not work. So be certain that your temp file is being saved to the same volume as your destination file!
And that's your neat little foray into file replacement on Windows. Exciting, eh?
OK so we know you're evil and won't tell us how to do stuff on a Mac out of fear that it might cleanse your corrupted soul. What else is new ? :)
Some of us keep trying to help you but you can only help an addict if they want it :)
Now that we have the prerequisite slam out of the way :) ... I'm not sure if the Mac OS ExchangeFiles or ExchangeObjects will work across volumes either.
It's been a while since I looked into that one
This does look pretty darned simple to use but I think you should spare the ponies just to make sure PETA doesn't get on your case
FYI - THANKS !
I just happen to need exactly this code today
I'm too sad to comment...I JUST LOST MY PONY--DARN IT!
Corbin, I just found one, could it be yours? Please describe fr verification and immediate pick up.
It probably isn't his. His I think died of typhoid.
and be careful about other thigns like making sure the file is not read only
the routine fails then as well