Olga
Olga

Reputation: 359

Pause the execution of Java if files are used

My application writes to Excel files. Sometimes the file can be used, in that case the FileNotFoundException thrown and then I do not know how to handle it better.

I am telling the user that the file is used and after that message I do not want to close the application, but to stop and wait while the file is available (assuming that it is opened by the same user). But I do not understand how to implement it. file.canWrite() doesn't work, it returns true even when the file is opened, to use FileLock and check that the lock is available I need to open a stream, but it throws FileNotFoundException (I've been thinking about checking the lock in a busy wait, I know that it is not a good solution, but I can't find another one).

This is a part of my code if it can help somehow to understand my problem:

File file = new File(filename);
FileOutputStream out = null; 
try {
    out = new FileOutputStream(file);
    FileChannel channel = out.getChannel();
    FileLock lock = channel.lock();
    if (lock == null) {
        new Message("lock not available");
            // to stop the program here and wait when the file is available, then resume 
    }
    // write here
    lock.release();
}
catch (IOException e) {
    new Message("Blocked");
    // or to stop here and then create another stream when the file is available
}

What makes it more difficult for me is that it writes to different files, and if the first file is available, but the second is not, then it will update one file and then stop, and if I restart the program, it will update it again, so I can't allow the program to write into files until all of them are available.

I believe that there should be a common solution, since it must be a common issue in Windows to deal with such cases, but I can't find it.

Upvotes: 0

Views: 3908

Answers (1)

Joni
Joni

Reputation: 111239

To wait until a file exists you can make a simple loop:

File file = new File(filename);
while (!file.exists()) {
    try { 
        Thread.sleep(100);
    } catch (InterruptedException ie) { /* safe to ignore */ }
}

A better solution could be using WatchService but it's more code to implement.

The File.canWrite method only tells you if a path can be written to; if the path names a file that doesn't exist it will return false. You could use the canRead method instead of exists in a loop like above.

To use a file locks, the file has to exist first, so that wouldn't work either.


The only way to be sure you can write to a file is to try to open it. If the file doesn't exist, the java.io API will create it. To open a file for writing without creating you can use the java.nio.file.Files class:

try (OutputStream out = Files.newOutputStream(file.toPath(),
                                              StandardOpenOption.WRITE))
{
    // exists and is writable
} catch (IOException) {
    // doesn't exist or can't be opened for writing 
}

Upvotes: 1

Related Questions