如何知道java(1.6)中的文件复制是“正在进行”/完成

我正在使用lastModified long值作为更改的指示,以特定间隔使用轮询在java(1.6)中编写目录监视实用程序。 我发现当我的轮询间隔很小(秒)并且复制的文件很大时,在实际完成文件复制之前会触发change事件。

我想知道是否有一种方法可以找到文件的状态,如传输,完成等。

环境: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); } 

此解决方案依赖于以下事实:如果另一个进程打开该文件,则无法打开该文件。 它将保持循环,直到达到超时值或文件可以打开。 需要根据应用程序的实际需要调整超时值。 我也尝试过使用channels和tryLock()的方法,但似乎没有必要。

你的意思是说你正在等待最后修改的时间来解决? 充其量只会有点昙花一现。

如何尝试使用写访问权限打开文件(当然是附加而不是截断文件)? 如果另一个进程仍在尝试写入它,那将不会成功。 这有点难看,特别是因为它可能是流控制(ick)使用exception的情况,但我认为它会起作用。

如果我正确理解了这个问题,那么您正在寻找一种方法来区分文件的复制是完整还是仍在进行中?

如何比较源文件和目标文件的大小(即file.length())? 如果它们相等,那么复制就完成了。 否则,它仍在进行中。

我不确定它是否有效,因为它仍然需要轮询。 但它“可能”有效。

您可以使用progressbar技术查看在线文件上传 – 它们使用OutputStreamListener和自定义编写器来通知侦听器有关写入的字节。

http://www.missiondata.com/blog/java/28/file-upload-progress-with-ajax-and-java-and-prototype/

使用Java上传文件(带进度条)

我们曾经监视文件大小更改以确定文件是否未完成。

我们使用Spring集成文件端点每200毫秒对一个目录进行轮询。

一旦检测到文件(无论它是否完整),我们有一个客户文件filter,它将有一个接口方法“accept(文件文件)”,返回一个标志,指示我们是否可以处理该文件。

如果filter返回False,则将忽略此FILE实例,并在下次轮询期间为同一过滤过程提取该FILE实例。

filter执行以下操作:

首先,我们得到它当前的文件大小。 我们将等待200毫秒(可以更少)并再次检查大小。 如果大小不同,我们将重试5次。 只有当文件大小停止增长时,文件才会被标记为COMPLETED。(即返回true)。

使用的示例代码如下:

 public class InCompleteFileFilter extends AbstractFileListFilter { protected Object monitor = new Object(); @Override protected boolean accept(F file) { synchronized (monitor){ File currentFile = (File)file; if(!currentFile.getName().contains("Conv1")){return false;} long currentSize = currentFile.length(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } int retryCount = 0; while(retryCount++ < 4 && currentFile.length() > currentSize){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } if(retryCount == 5){ return false; }else{ return true; } } } }