tags:

views:

427

answers:

3

I'm trying to implement the following operation in Java and am not sure how:

/*
 * write data (Data is defined in my package)
 * to a file only if it does not exist, return success
 */
boolean writeData(File f, Data d)
{
    FileOutputStream fos = null;
    try 
    {
        fos = atomicCreateFile(f);
        if (fos != null)
        {
            /* write data here */
            return true;
        }
        else
        {
            return false;
        }
    }
    finally
    {
        fos.close();  // needs to be wrapped in an exception block
    }
}

Is there a function that exists already that I can use for atomicCreateFile()?

edit: Uh oh, I'm not sure that File.createNewFile() is sufficient for my needs. What if I call f.createNewFile() and then between the time that it returns and I open the file for writing, someone else has deleted the file? Is there a way I can both create the file and open it for writing + lock it, all in one fell swoop? Do I need to worry about this?

+6  A: 

File.createNewFile() only creates a file if one doesn't already exist.

EDIT: Based on your new description of wanting to lock the file after it's created you can use the java.nio.channels.FileLock object to lock the file. There isn't a one line create and lock though like you are hoping. Also, see this SO thread.

Taylor Leese
doh! how did I miss that? :/ thanks. My mind's been in C++ land.
Jason S
updated my answer based on your edit
Taylor Leese
ok, thanks. Well it sounds like I have to think carefully about exceptional conditions. (e.g. if the createNewFile() succeeds but opening a file channel and getting a file lock fails)
Jason S
+4  A: 
OscarRyz
Sorry for the mis-edit.
Joachim Sauer
Joachim: No problem, so uses optimistic lock for editing
OscarRyz
Thanks, I did read the note, that's what triggered the Uh oh.
Jason S
(Unfortunately there doesn't seem to be a repository of Java I/O paradigms, aside from manually exploring the platform javadocs, that says these are all the tools you have available... File and FileLock are in completely different packages, sometimes you use FileChannel, sometimes you use FileOutputStream... makes my head spin sometimes.)
Jason S
Like an almanac ? :) http://www.exampledepot.com/egs/java.nio/SetFileLock.html
OscarRyz
I found that one too, but I'm not using the file as a lock, I just want to be 100% sure that if I write to the file I'm the first one doing so, and no one else is touching it while I'm writing to it.
Jason S
A: 

Why can't you test using File#exists?

Geo
because between the time you test using File.exists(), and you go to create a file if it doesn't exist, someone else might have created the file first.
Jason S
Because between the time `exists()` returns false and he constructs the `FileOutputStream` some other process could jump in and create the file. A classical race condition.
Joachim Sauer
(the same way I slipped in that comment just ahead of Joachim. :-)
Jason S
Excellent demonstration, indeed ;-)
Joachim Sauer