简体   繁体   English

如何在java中打开文件之前等待windows进程完成

[英]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. 这是通过轮询和使用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. 现在程序已设置好,一旦收到新文件,它就会调用另一个打开文件的java程序,并验证它是否是正确的文件。 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. 我的问题是,由于轮询在指定的秒数后发生,可能会出现在该目录中复制文件并因此被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"). 这会引发IOException,因为尝试打开它进行验证的其他java程序不能(“File正被另一个进程使用”)。

Is there a way I can know when windows has finished copying and then call the second program to do the validations from java? 有没有办法让我知道Windows何时完成复制,然后调用第二个程序从java进行验证?

I will be more than happy to post code snippets if someone needs them in order to help. 如果有人需要它们以帮助我,我将非常乐意发布代码片段。

Thanks 谢谢

Thanks a lot for all the help, I was having the same problem with WatchEvent. 非常感谢所有的帮助,我遇到了与WatchEvent相同的问题。 Unfortunately, as you said, file.canRead() and file.canWrite() both return true, even if the file still locked by Windows. 不幸的是,正如你所说,file.canRead()和file.canWrite()都返回true,即使文件仍被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. 所以我发现如果我尝试用同一个名称“重命名”它,我知道Windows是否正在使用它。 So this is what I did: 所以这就是我做的:

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }

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. 如果你可以控制或至少与复制文件的程序进行通信,那将是一块蛋糕,但我想这不可能用于Windows。 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. 我不得不用SFU软件处理类似的问题,我通过循环尝试打开文件进行写入直到它变得可用来解决它。

To avoid high CPU usage while looping, checking the file can be done at an exponential distribution rate. 为了避免循环时CPU使用率过高,可以以指数分布速率检查文件。

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);

I think you can create the File object and then use canRead or canWrite to know whether file ready to be used by the other java program. 我认为您可以创建File对象,然后使用canReadcanWrite来了解文件是否可以被其他java程序使用。

http://docs.oracle.com/javase/6/docs/api/java/io/File.html http://docs.oracle.com/javase/6/docs/api/java/io/File.html

Other option is to try to Open file on first program and if it throws the exception then dont call the other java program. 其他选择是尝试在第一个程序上打开文件,如果它抛出异常,则不要调用其他java程序。 But I ll recommend the above 'File option. 但我会推荐上面的'File选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM