views:

317

answers:

3

I have a very common situation. I have a file, and I need to entirely overwrite that file with new contents. However, the original file is accessed on every page load (this is a web app), so it can't be missing for very long. A few ms is OK (though not ideal), a second is not OK.

Right now I do this by writing a temp file to the same directory and then renaming that temp file to the name of the new file. I'm just using the normal File::Temp and "rename" to do this, in Perl. I was wondering--is there some other recommended/better way to do this? Preferably one that doesn't require a CPAN module, as this is the only place in my system that I need to do this, and I don't want a whole new dependency just for this.

Oh, and all of this has to work on Windows, Linux, BSD, OS X, Solaris, and most other common platforms.

Here is the code in question, for those interested.

+8  A: 

Your method seems just fine. It's quick, it's atomic, it uses core modules only, and File::Temp is a safe way to deal with temporary files. What more do you need?

Adam Bellaire
Well, possibly just a confirmation that this really is the best way. :-) I was mostly just wondering if there was any other particularly recommended way to do it, since I was looking at the code in question anyhow (to fix a bug) and I figured now would be a good time to improve it if needed. :-)
Max
+4  A: 

I'd do it the same way you're doing it. At least on Unix-type OSes, a file rename is guaranteed to be atomic so you won't have any instants where either the original or the new files isn't there.

Paul Tomblin
A: 

Rename is sufficient. However:

Is your temporary file at risk for race conditions? The filename should be randomized so nobody can cause problems by inserting their own file. Use an interface to mkstemp() if possible.

HUAGHAGUAH
I'm pretty sure File:Temp is properly randomized.
Paul Tomblin
Yeah, File::Temp is properly randomized, that's what the XXXXX is for in the code.
Max
ysth