java - Le processus ne peut pas accéder au fichier car ce fichier est utilisé par un autre processus

J'ai un morceau de code qui surveille un répertoire pour l'ajout de fichiers. Chaque fois qu'un nouveau fichier est ajouté à l'annuaire, le contenu du fichier sont repris et publié sur kafka, puis le fichier est supprimé.

Cela fonctionne quand je fais une seule requête, mais dès que j'ai soumis mon code à 5 ou 10 demande de l'utilisateur à partir de jMeter, le contenu est publié sur kafka avec succès, mais le code n'est pas en mesure de supprimer le fichier. Je reçois un FileSystemException avec un message qui The process cannot access the file because it is being used by another process..

Je pense qu'il y a quelques problème de concurrence qui je suis incapable de voir.

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);
}
}
}

Exception Du Journal :

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)
Se pourrait-il que le processus qui crée le fichier n'a pas fini de créer il (n'a pas fermé) avant d'essayer de le lire et de le supprimer?
Par ailleurs, la WatchService est fermer, donc de mettre newWatchService() à l'intérieur d'un try-with-resources. Aussi, puisque vous êtes à l'aide de nio partout ailleurs, pour plus de cohérence au lieu de new File(...).toPath() ne faxFolder.resolve(filename).
Kyriacou: depuis le WatchEvent’contexte est déjà un Path lorsque vous regardez un système de fichiers, même la conversion en chaîne de caractères est obsolète et faxFolder.resolve((Path)event.context()) est suffisant. Je pense que vous avez raison, en réaction à la création de l'événement immédiatement, ça ne donne pas le créateur de suffisamment de temps pour fermer le fichier. Il est intéressant de noter, sur mon système, qui a l'effet inverse: la lecture du fichier échoue car il n'est pas encore écrite, mais la suppression des œuvres, comme le système reporte la suppression effective de à la point de, le créateur ferme le fichier.
les bons points. Je pense (je besoin de le tester) que lorsqu'un nouveau fichier est créé, vous obtenez deux événements: d'abord, l'entrée de création, suivi par une entrée de modification (lorsque l'horodatage est mis à jour à la clôture du dossier). Le fichier ne doit être lu après l'événement de modification. (Et peut-être qu'après un délai d'attente, dans le cas d'un fichier vide est créé et à gauche.)
Kyriacou: il peut y avoir plus d'un événement de modification pendant que l'autre application est l'écriture dans le fichier. Donc, vous avez à l'installation d'une minuterie qui initie votre action un certain temps après la dernière modification de l'événement, la réinitialisation de la minuterie sur chaque modification. Et c'est encore seulement le traitement de l'affaire que l'autre application crée le fichier, écrit et il se ferme tout droit-forwardly...

OriginalL'auteur Furquan Ahmed | 2016-11-24