我在一个文件夹上运行了一个监视服务,当我试图使用evenkind==modify修改现有文件时(基本上粘贴同一个文件而不删除当前文件),我得到了filenotfoundexception(进程无法访问该文件,因为它正被另一个进程使用)
if (eventKind == StandardWatchEventKinds.ENTRY_MODIFY) {
String newFileChecksum = null;
if (eventPath.toFile().exists()) {
newFileChecksum = getFileChecksum(eventPath.toFile());
}
if (fileMapper.containsKey(eventPath)) {
String existingFileChecksum = fileMapper.get(eventPath);
if (!existingFileChecksum.equals(newFileChecksum)) {
fileMapper.replace(eventPath, existingFileChecksum, newFileChecksum);
log.info("listener.filemodified IN");
for (DirectoryListener listener : this.listeners) {
listener.fileModified(this, eventPath);
}
log.info("listener.filemodified OUT");
} else {
log.info("existing checksum");
log.debug(String.format(
"Checksum for file [%s] has not changed. Skipping plugin processing.",
eventPath.getFileName()));
}
}
}
在调用…getfilechecksum()时的代码中
if (eventPath.toFile().exists()) {
newFileChecksum = getFileChecksum(eventPath.toFile());
}
所以,理想情况下,eventpath.tofile().exists()为true,所以如果调用getfilechecksum()时,代码将进入方法。。。
private synchronized String getFileChecksum(File file) throws IOException, NoSuchAlgorithmException {
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
FileInputStream fis = null;
if(file.exists()) {
try {
fis = new FileInputStream(file);
} catch(Exception e) {
e.printStackTrace();
}
} else {
log.warn("File not detected.");
}
byte[] byteArray = new byte[1024];
int bytesCount = 0;
while ((bytesCount = fis.read(byteArray)) != -1) {
md5Digest.update(byteArray, 0, bytesCount);
};
fis.close();
byte[] bytes = md5Digest.digest();
StringBuilder stringBuilder = new StringBuilder();
for (int i=0; i< bytes.length ;i++) {
stringBuilder.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
return stringBuilder.toString();
}
}
出现异常fis=newfileinputstream(文件);即使文件夹中存在该文件。
filenotfoundexception(进程无法访问该文件,因为另一个进程正在使用它。)
我创建了一个randomaccessfile和一个通道来释放文件上的任何锁,但它不起作用。请告诉我这里会发生什么。
//更新-->这是我的无限while循环,
发生了什么事?当我放置一个文件时,调用1 create和2 update,假设,当我删除该文件时,调用1 delete和1 modify,如果我将同一个文件放回文件夹,则调用create,但在create完成之前,调用modify。而create没有运行,而modify正在运行。
我将thread.sleep(500)放在
WatchKey wk = watchService.take();
Thread.sleep(500)
for (WatchEvent<?> event : wk.pollEvents()) {
但我不认为我有理由在这里睡觉。请帮忙
watchservice watchservice=null;watchkey watchkey=null;
while (!this.canceled && (watchKey == null)) {
watchService = watchService == null
? FileSystems.getDefault().newWatchService() : watchService;
watchKey = this.directory.register(watchService,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_CREATE);
}
while (!this.canceled) {
try {
WatchKey wk = watchService.take();
for (WatchEvent<?> event : wk.pollEvents()) {
Kind<?> eventKind = event.kind();
System.out.println("Event kind : " + eventKind);
Path dir = (Path)wk.watchable();
Path eventPath = (Path) event.context();
Path fullPath = dir.resolve(eventPath);
fireEvent(eventKind, fullPath);
}
wk.reset();
}
3条答案
按热度按时间kxeu7u2r1#
我有一个更好的方法,在var isfileready上使用while循环,就像这样。。。
在里面,同时创造一个尝试和捕捉。
这会解决你的问题。
zyfwsgd62#
watchservice非常冗长,可能会报告多个条目的\u修改事件以执行保存操作—即使另一个应用程序正在执行部分操作或重复执行写入操作。当另一个应用程序仍在编写时,您的代码可能正在对修改事件执行操作,并且可能有第二个条目正在进行修改。
使用watchservice的一个更安全的策略是整理接收到的事件,并且只在暂停时对更改采取行动。类似这样的操作将确保您在第一个事件上阻塞,但在对上一个事件集执行操作之前,会以较小的超时轮询监视服务,以查看是否存在更多更改:
如果还希望使用modify执行create和delete操作,则必须整理并忽略一些早期事件,因为最后记录的事件类型可能优先于先前记录的类型。例如,如果调用take(),则轮询(1),直到没有新的报告:
任何delete-then-create=>您可能需要将其视为modify
任何create-then-modify=>您可能希望将其视为create
任何创建或修改,然后删除=>视为删除
你的逻辑也只想在
modified.size() + created.size() + deleted.size()
在两次运行之间更改。kadbb4593#
让我猜猜。。。
修改文件时调用modify事件。要修改文件,您最有可能使用一个单独的工具,如记事本,打开并锁定文件。
你的观察者得到一个事件,文件被修改了(现在),但是你不能再修改它(fileinputstream想要这样做),因为它已经被锁定了。