Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Wait for windows process to finish before opening file in java

I have a implemented a listener that notifies if we receive a new file in a particular directory. This is implemented by polling and using a TimerTask. Now the program is so set up that once it receives a new file it calls another java program that opens the file and validates whether it is the correct file. My problem is that since the polling happens a specified number of seconds later there can arise a case in which a file is being copied in that directory and hence is locked by windows.

This throws an IOException since the other java program that tries to open it for validation cannot ("File is being used by another process").

Is there a way I can know when windows has finished copying and then call the second program to do the validations from java?

I will be more than happy to post code snippets if someone needs them in order to help.

Thanks

like image 370
Eosphorus Avatar asked Feb 22 '23 06:02

Eosphorus


2 Answers

Thanks a lot for all the help, I was having the same problem with WatchEvent. Unfortunately, as you said, file.canRead() and file.canWrite() both return true, even if the file still locked by Windows. So I discovered that if I try to "rename" it with the same name, I know if Windows is working on it or not. So this is what I did:

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }
like image 142
jfajunior Avatar answered Feb 24 '23 18:02

jfajunior


This one is a bit tricky. It would have been a piece of cake if you could control or at least communicate with the program copying the file but this won't be possible with Windows I guess. I had to deal with a similar problem a while ago with SFU software, I resolved it by looping on trying to open the file for writing until it becomes available.

To avoid high CPU usage while looping, checking the file can be done at an exponential distribution rate.

EDIT A possible solution:

File fileToCopy = File(String pathname);
int sleepTime = 1000; // Sleep 1 second
while(!fileToCopy .canWrite()){
    // Cannot write to file, windows still working on it
    Sleep(sleepTime);
    sleepTime *= 2; // Multiply sleep time by 2 (not really exponential but will do the trick)
    if(sleepTime > 30000){ 
        // Set a maximum sleep time to ensure we are not sleeping forever :)
        sleepTime = 30000;
    }
}
// Here, we have access to the file, go process it
processFile(fileToCopy);
like image 28
GETah Avatar answered Feb 24 '23 19:02

GETah