Прочитайте файл дважды из папки и получите "Процесс не может получить доступ к файлу, потому что он используется другим процессом"
У меня есть простой класс, который подключен к папке, и я хочу удалить все обычные файлы, которые создаются, но когда я читаю файл с тем же именем (один и тот же файл вставляется в папку более одного или двух раз), я получаю ошибка
Exception in thread "main" java.lang.RuntimeException: java.nio.file.FileSystemException: c:\Temp\reader\msg.xml: The process cannot access the file because it is being used by another process.
at com.project.test.Reader.lambda$0(Reader.java:38)
at com.project.test.Reader$$Lambda$1/1418481495.accept(Unknown Source)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at com.project.test.Reader.main(Reader.java:28)
Caused by: java.nio.file.FileSystemException: c:\Temp\reader\msg.xml: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
at java.nio.file.Files.delete(Files.java:1126)
at com.project.test.Reader.lambda$0(Reader.java:35)
... 4 more
Вот мой класс читателя:
package com.project.test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
public class Reader {
public static void main(String[] args) {
Path path = Paths.get("c:\\Temp\\reader\\");
WatchService watchService;
try {
watchService = path.getFileSystem().newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey watchKey = null;
while (true) {
watchKey = watchService.poll(5, TimeUnit.SECONDS);
if (watchKey != null) {
try(Stream<WatchEvent<?>> events = watchKey.pollEvents().stream()) {
events.forEach(event -> {
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
@SuppressWarnings("unchecked")
Path name = ((WatchEvent<Path>) event).context();
Path file = path.resolve(name);
try {
if (Files.isRegularFile(file)) {
Files.delete(file);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
watchKey.reset();
}
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Разве вы не знаете, что не так? Я ожидаю, что должно пропустить некоторое "закрытие" в файле, но путь является только целью для файла и не должен быть закрыт, не так ли? Спасибо за все советы.
1 ответ
Если вы читаете javadoc для WatchService, он говорит, что реализация зависит от операционной системы, т.е. для некоторых операционных систем при добавлении файла в папку может быть создано более одного события:
Например, когда файл в наблюдаемом каталоге изменяется, это может привести к одному событию ENTRY_MODIFY в некоторых реализациях, но к нескольким событиям в других реализациях.
Я догадываюсь, что это происходит и в твоем случае.
Вот некоторые похожие обсуждения:
Java 7 WatchService - игнорирование нескольких вхождений одного и того же события
Что бы я сделал, чтобы это работало, - это сохранить путь к файлу, который я собираюсь удалить, в параллельном наборе и попытаться удалить его, только если текущий путь еще не находится в этом наборе.