如何在java中知道文件复制是否“正在进行”/是否已完成(1.6)
我正在java(1.6)中编写一个目录监视实用程序,使用轮询以特定的间隔使用长值作为更改的指示。我发现,当我的轮询间隔很小(秒)并且复制的文件很大时,则在文件复制实际完成之前触发更改事件。lastModified
我想知道是否有一种方法可以找到文件的状态,例如正在传输,完成等。
环境: Java 1.6;预计将在Windows和Linux上工作。
我正在java(1.6)中编写一个目录监视实用程序,使用轮询以特定的间隔使用长值作为更改的指示。我发现,当我的轮询间隔很小(秒)并且复制的文件很大时,则在文件复制实际完成之前触发更改事件。lastModified
我想知道是否有一种方法可以找到文件的状态,例如正在传输,完成等。
环境: Java 1.6;预计将在Windows和Linux上工作。
我过去使用过两种与平台无关的方法。
1/ 这是针对FTP传输的,我控制了放置的内容,因此它可能不直接相关。
基本上,无论放一个文件是什么,当它完成时,也会放一个小的(可能是零字节的)虚拟文件,称为(例如)。file.txt
file.txt.marker
这样,监视工具只需查找要显示的标记文件,当它出现时,它就知道真实文件已完成。然后,它可以处理真实文件并删除标记。
2/ 持续时间不变。
让监视器程序等待,直到文件保持不变 N 秒(其中 N 可以合理地保证足够大,以至于文件将完成)。
例如,如果文件大小在 60 秒内未更改,则很有可能它已完成。
在不认为文件已经完成,只是因为文件上没有活动,以及一旦文件完成即可开始处理它之间有一个平衡行为。与 FTP 相比,这对于本地复制来说问题不大。
这个解决方案对我有用:
File ff = new File(fileStr);
if(ff.exists()) {
for(int timeout = 100; timeout>0; timeout--) {
RandomAccessFile ran = null;
try {
ran = new RandomAccessFile(ff, "rw");
break; // no errors, done waiting
} catch (Exception ex) {
System.out.println("timeout: " + timeout + ": " + ex.getMessage());
} finally {
if(ran != null) try {
ran.close();
} catch (IOException ex) {
//do nothing
}
ran = null;
}
try {
Thread.sleep(100); // wait a bit then try again
} catch (InterruptedException ex) {
//do nothing
}
}
System.out.println("File lockable: " + fileStr +
(ff.exists()?" exists":" deleted during process"));
} else {
System.out.println("File does not exist: " + fileStr);
}
此解决方案依赖于这样一个事实,即如果另一个进程打开了文件,则无法打开该文件进行写入。它将一直保持在循环中,直到达到超时值或可以打开文件。超时值需要根据应用程序的实际需求进行调整。我也尝试了这种方法与通道和tryLock(),但它似乎没有必要。