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

如何在java中打开文件之前等待windows进程完成,java,io,wait,timertask,Java,Io,Wait,Timertask,我已经实现了一个侦听器,它会通知我们是否在特定目录中收到新文件。这是通过轮询和使用TimerTask实现的。 现在,程序的设置是这样的,一旦它收到一个新文件,它就会调用另一个java程序来打开该文件并验证它是否是正确的文件。我的问题是,由于轮询发生在指定的秒数之后,因此可能会出现一种情况,即文件被复制到该目录中,因此被windows锁定 这会引发IOException,因为尝试打开它进行验证的其他java程序无法(“文件正被另一个进程使用”) 有没有办法知道windows何时完成复制,然后调用第

我已经实现了一个侦听器,它会通知我们是否在特定目录中收到新文件。这是通过轮询和使用TimerTask实现的。 现在,程序的设置是这样的,一旦它收到一个新文件,它就会调用另一个java程序来打开该文件并验证它是否是正确的文件。我的问题是,由于轮询发生在指定的秒数之后,因此可能会出现一种情况,即文件被复制到该目录中,因此被windows锁定

这会引发IOException,因为尝试打开它进行验证的其他java程序无法(“文件正被另一个进程使用”)

有没有办法知道windows何时完成复制,然后调用第二个程序从java进行验证

如果有人需要帮助,我会非常乐意发布代码片段


谢谢

我认为您可以创建
文件
对象,然后使用
canRead
canWrite
来了解该文件是否准备好供其他java程序使用


另一种选择是尝试在第一个程序上打开文件,如果它抛出异常,则不要调用另一个java程序。但是我会推荐上面的
文件
选项。

这个选项有点棘手。如果你能控制或至少与复制文件的程序进行通信,那将是小菜一碟,但我想这在Windows上是不可能的。不久前,我不得不用软件处理一个类似的问题,我通过循环尝试打开文件进行编写,直到文件可用为止,从而解决了这个问题

为了避免循环时CPU的高使用率,可以按一定的速率检查文件

编辑可能的解决方案:

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

非常感谢所有的帮助,我在WatchEvent上也遇到了同样的问题。 不幸的是,正如您所说,file.canRead()和file.canWrite()都返回true,即使文件仍然被Windows锁定。所以我发现,如果我尝试用相同的名称“重命名”它,我就知道Windows是否正在处理它。这就是我所做的:

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

canRead实际上并没有说明该文件是否已准备好供其他程序使用。我在复制文件的过程中尝试过使用它,但奇怪的是,由于文件已被windows锁定,当我期望值为false时,该值返回true。但是您应该尝试
canWrite
这听起来像是一个有效的选项。您能否给出一个小示例代码,说明如果失败,我如何实现指数循环要打开文件吗?这样行。谢谢。但是,即使windows有锁,filetoCopy.canWrite()或filetoCopy.canRead()也将始终为真。因此,我们需要尝试打开文件并捕获异常,而不是while循环。再次感谢,我会记下这个resolved@user1074440很高兴它成功了:)fileToCopy.canWrite()如果文件被另一个进程打开,则应返回false。但你的建议(以及我在答案顶部提出的建议)应该能起作用。总是很乐意提供帮助:)是的,我知道,但我不知道为什么即使在文件打开时它也会一直返回true,但后来当另一个java程序试图打开它时却出现了错误。havezx建议使用canRead()选项。但是我能够通过在while循环中使用try-catch块来实现您的代码,以保持检查,直到文件可以打开为止。使用catch块编写代码不是最佳做法,但它确实有效:D@Eosphorus文件可以以不同的模式打开,包括使用或不使用独占访问。编程语言通常在其“openfile”语句语法中支持一些子句来设置打开模式。试着在记事本中打开一个文本文件,同时在MS Word中打开它。尝试将文件保存在记事本中,您将得到一个错误,该文件被另一个进程使用。尝试将其保存在Word中,它将按预期保存。这是因为记事本和Word以不同的模式打开文件。我猜
canRead()
canWrite()
是基于开放模式的。其他java程序必须读或写?这是一个很好的解决方法@jfajunior。我也是这样做的。我只是试图打开文件,它会给出一个异常,因为windows正在处理它。所以我发现了一个异常,像你一样让线程休眠,并在上面建议的指数循环之后再次尝试。很高兴这篇文章对你有所帮助