FileNotFound异常,即使在java中的监视服务过程中文件已就位

FileNotFound异常,即使在java中的监视服务过程中文件已就位,java,filenotfoundexception,watchservice,Java,Filenotfoundexception,Watchservice,我在一个文件夹上运行了一个监视服务,当我试图使用evenKind==modify(基本上粘贴同一个文件而不删除当前文件)修改现有文件时,我得到了FileNotFoundException(该进程无法访问该文件,因为它正被另一个进程使用) 在调用…getFileChecksum()时的代码中 if (eventPath.toFile().exists()) { newFileChecksum = getFileChecksum(eventPath.toFile()); } 因

我在一个文件夹上运行了一个监视服务,当我试图使用evenKind==modify(基本上粘贴同一个文件而不删除当前文件)修改现有文件时,我得到了FileNotFoundException(该进程无法访问该文件,因为它正被另一个进程使用)

在调用…getFileChecksum()时的代码中

if (eventPath.toFile().exists()) {

        newFileChecksum = getFileChecksum(eventPath.toFile());

}
因此,理想情况下,eventPath.toFile().exists()为真,因此,如果调用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();
    }
}
private synchronized String getFileChecksum(文件文件)抛出IOException、nosuchagorithmexception{
MessageDigest md5Digest=MessageDigest.getInstance(“MD5”);
FileInputStream fis=null;
if(file.exists()){
试一试{
fis=新文件输入流(文件);
}捕获(例外e){
e、 printStackTrace();
}
}否则{
log.warn(“未检测到文件”);
}
字节[]字节数组=新字节[1024];
int字节数=0;
while((字节数=fis.read(字节数组))!=-1){
md5Digest.update(字节数组,0,字节计数);
};
fis.close();
byte[]bytes=md5Digest.digest();
StringBuilder StringBuilder=新的StringBuilder();
for(int i=0;i
异常即将出现fis=newfileinputstream(文件)即使文件夹中存在该文件

FileNotFoundException(该进程无法访问该文件,因为它正被另一进程使用。)

我创建了一个RandomAccessFile和一个通道来释放文件上的任何锁,但它不起作用。请说明这里可能发生的情况

//更新-->这是我的无限while循环

发生了什么事?当我放置一个文件时,1 create2 update被调用,假设当我删除该文件时,1 delete 1 modify被调用,如果我将同一个文件放回文件夹,我得到create,但在create完成之前,会调用modify。并且create没有运行,而modify正在运行

我通过将Thread.sleep(500)放在

WatchKey wk=watchService.take(); 线程。睡眠(500) for(WatchEvent事件: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();

    }
while(!this.cancelled&&(watchKey==null)){
watchService=watchService==null
?FileSystems.getDefault().newWatchService():watchService;
watchKey=this.directory.register(watchService,
StandardWatchEventTypes.ENTRY\u修改,StandardWatchEventTypes.ENTRY\u删除,
StandardWatchEventTypes.ENTRY(创建);
}
而(!this.cancelled){
试一试{
WatchKey wk=watchService.take();
for(WatchEvent事件:wk.pollEvents()){
种类eventKind=event.Kind();
System.out.println(“事件种类:+eventKind”);
Path dir=(Path)wk.watchable();
Path eventPath=(Path)event.context();
Path fullPath=dir.resolve(eventPath);
fireEvent(eventKind,fullPath);
}
wk.reset();
}
让我猜猜

修改文件时会调用modify事件。要修改文件,最有可能使用单独的工具(如记事本)打开并锁定文件


您的观察者会收到一个事件,即文件被修改(现在),但您不能再次修改它(fileinputstream希望这样做)因为它已经被锁定。

WatchService非常冗长,可能会报告多个条目\u修改事件以进行保存操作,即使另一个应用程序正在执行部分操作或重复执行写入操作。当另一个应用程序仍在写入时,您的代码可能正在处理修改事件,并且可能会有第二个条目\u修改

使用WatchService的一个更安全的策略是,整理您收到的事件,并仅在出现暂停时对更改采取行动。这样可以确保您阻止第一个事件,但在对上一组事件采取行动之前,先以较小的超时轮询WatchService,以查看是否存在更多更改:

WatchService ws = ...
HashSet<Path> modified = new HashSet<>();

while(appIsRunning) {
    int countNow = modified.size();
    WatchKey k = countNow == 0 ? ws.take() : ws.poll(1, TimeUnit.MILLISECONDS);
    if (k != null) {
        // Loop through k.pollEvents() and put modify file path into modified set:
        // DO NOT CALL fireEvent HERE, save the path instead:
        ...
        if (eventKind == ENTRY_MODIFY)
            modified.add(filePath);
    }
    // Don't act on changes unless no new events:
    if (countNow == modified.size()) {
        // ACT ON modified list here - the watch service did not report new changes
        for (Path filePath : modified) {
           // call fireEvent HERE:
           fireEvent(filePath);
        }

        // reset the list so next watch call is take() not poll(1)
        modified.clear();
    }
}
WatchService ws=。。。
HashSet modified=新HashSet();
同时(应用程序运行){
int countNow=modified.size();
WatchKey k=countNow==0?ws.take():ws.poll(1,TimeUnit.ms);
如果(k!=null){
//循环执行k.pollEvents(),并将修改文件路径放入修改集:
//不要在此处调用fireEvent,而是保存路径:
...
if(eventKind==ENTRY\u MODIFY)
modified.add(文件路径);
}
//除非没有新事件,否则不要对更改采取行动:
如果(countNow==modified.size()){
//按此处修改的列表操作-监视服务未报告新的更改
对于(路径文件路径:已修改){
//在此处调用fireEvent:
fireEvent(文件路径);
}
//重置列表,以便下一个监视调用是take()而不是poll(1)
修改的.clear();
}
}
如果您还想使用MODIFY查找创建和删除操作,则必须整理并忽略一些早期事件,因为最后记录的事件类型可能优先于以前记录的类型。例如,如果调用take(),则轮询(1),直到无
        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();

    }
WatchService ws = ...
HashSet<Path> modified = new HashSet<>();

while(appIsRunning) {
    int countNow = modified.size();
    WatchKey k = countNow == 0 ? ws.take() : ws.poll(1, TimeUnit.MILLISECONDS);
    if (k != null) {
        // Loop through k.pollEvents() and put modify file path into modified set:
        // DO NOT CALL fireEvent HERE, save the path instead:
        ...
        if (eventKind == ENTRY_MODIFY)
            modified.add(filePath);
    }
    // Don't act on changes unless no new events:
    if (countNow == modified.size()) {
        // ACT ON modified list here - the watch service did not report new changes
        for (Path filePath : modified) {
           // call fireEvent HERE:
           fireEvent(filePath);
        }

        // reset the list so next watch call is take() not poll(1)
        modified.clear();
    }
}
var isFileReady = false;

while(!isFile...) {
}
try {

FileInputStream fis = new FileInputStream();

isFileReady = true;
} catch () {
catch exception or print file not ready.
}