4

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

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

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

如果有人需要它们以提供帮助,我将非常乐意发布代码片段。

谢谢

4

3 回答 3

5

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

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }
于 2013-03-20T20:47:17.393 回答
3

这个有点棘手。如果您可以控制或至少与复制文件的程序进行通信,那将是小菜一碟,但我猜这在 Windows 上是不可能的。不久前我不得不用SFU软件处理类似的问题,我通过循环尝试打开文件进行写入来解决它,直到它变得可用。

为避免循环时 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);
于 2011-11-30T23:40:38.160 回答
0

我认为您可以创建File对象然后使用canReadcanWrite知道文件是否已准备好供其他 java 程序使用。

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

其他选项是尝试在第一个程序上打开文件,如果它抛出异常,则不要调用其他 java 程序。但我会推荐上述'File选项。

于 2011-11-30T23:40:04.230 回答