ファイルを追加するディレクトリを監視するコードがあります。新しいファイルがディレクトリに追加されるたびに、ファイルの内容が選択され、kafkaに公開され、ファイルが削除されます。java - プロセスが別のプロセスで使用されているため、ファイルにアクセスできません。
これは私が1回のリクエストをしたときに動作しますが、コードをjMeterから5または10のユーザー要求に従わせると、内容はkafkaに正常に公開されますが、コードはファイルを削除できません。私はThe process cannot access the file because it is being used by another process.
というメッセージでFileSystemException
を得る。
私は見ることができないいくつかの並行性の問題があると思います。助けてください !
public void monitor() throws IOException, InterruptedException {
Path faxFolder = Paths.get(TEMP_FILE_LOCATION);
WatchService watchService = FileSystems.getDefault().newWatchService();
faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
boolean valid = true;
do {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
String fileName = event.context().toString();
publishToKafka(new File(TEMP_FILE_LOCATION + fileName).toPath(), "topic");
}
}
valid = watchKey.reset();
} while (valid);
}
private void publishToKafka(Path path, String topic) {
try (BufferedReader reader = Files.newBufferedReader(path)) {
String input = null;
while ((input = reader.readLine()) != null) {
kafkaProducer.publishMessageOnTopic(input, topic);
}
} catch (IOException e) {
LOG.error("Could not read buffered file to send message on kafka.", e);
} finally {
try {
Files.deleteIfExists(path); // This is where I get the exception
} catch (IOException e) {
LOG.error("Problem in deleting the buffered file {}.", path.getFileName(), e);
}
}
}
例外ログ:
java.nio.file.FileSystemException: D:\upload\notif-1479974962595.csv: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source)
at sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(Unknown Source)
at java.nio.file.Files.deleteIfExists(Unknown Source)
at com.panasonic.mdw.core.utils.MonitorDirectory$FileContentPublisher.publishToKafka(MonitorDirectory.java:193)
at com.panasonic.mdw.core.utils.MonitorDirectory$FileContentPublisher.sendData(MonitorDirectory.java:125)
at com.panasonic.mdw.core.utils.MonitorDirectory$FileContentPublisher.run(MonitorDirectory.java:113)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
ファイルを作成して削除しようとする前に、ファイルを作成するプロセスが作成を完了していない(閉じていない)ことはありますか? –
ところで、WatchServiceはクローズ可能ですので、try-with-resourcesの中に 'newWatchService()'を入れてください。また、あなたはどこにでもnioを使っているので、 'new File(...)の代わりに一貫性を持たせるためにtoPath()'は 'faxFolder.resolve(filename)'を実行します。 –
@Klitos Kyriacou:ファイルシステムを見ているときに 'WatchEvent'のコンテキストが既に' Path'であるため、stringへの変換も廃止され、 'faxFolder.resolve((Path)event.context())'で十分です。私はあなたが正しいと思う、作成イベントに反応することは、すぐにクリエイターにファイルを閉じるのに十分な時間を与えるものではない。興味深いことに、私のシステムでは、これとは逆の効果があります。ファイルの読み込みは失敗しますが、ファイルの読み込みは失敗しますが、実際の削除がポイントに実際に延期されるので、クリエイターはファイルを閉じます。 – Holger