我正在使用lastModifiedlong值作为更改的指示,以特定间隔使用轮询在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);
}
Run Code Online (Sandbox Code Playgroud)
此解决方案依赖于以下事实:如果另一个进程打开文件,则无法打开文件进行写入.它将保持循环,直到达到超时值或文件可以打开.需要根据应用程序的实际需要调整超时值.我也尝试过使用channels和tryLock()的方法,但似乎没有必要.
你的意思是说你在等待时机lastModified解决?充其量这会有点碰运气。
尝试使用写访问权限打开文件(当然是追加而不是截断文件)怎么样?如果另一个进程仍在尝试写入它,则不会成功。这有点难看,特别是因为它可能是使用异常进行流量控制的情况(ick),但我认为它会起作用。