La méthode Java File peut-elle & # 8220; canWrite () & # 8221; verrouillage de soutien?

StackOverflow https://stackoverflow.com/questions/122282

  •  02-07-2019
  •  | 
  •  

Question

J'ai une application Java qui surveille un dossier pour les fichiers XML entrants. Lorsqu'un nouveau fichier est détecté, je dois tester que le fichier n'est pas en cours de mise à jour et qu'il est fermé. Je pense utiliser le Fichier. canWrite () pour le tester. Y at-il un problème avec cela? Est-ce un bon moyen de vérifier qu'un fichier a été complètement écrit?

Les autres idées que je lance sont les suivantes:

  • Analyser le fichier XML entrant et tester que la balise de fermeture est là.
  • Recherchez le caractère EoF.

Je ne suis pas sûr que l'une de ces méthodes gérera tous les scénarios.

Était-ce utile?

La solution

Non, canWrite n'est pas adapté à cette fin. En général, le fichier sera accessible en écriture, même si un autre processus est en cours d'écriture.

Vous avez besoin d'un protocole de niveau supérieur pour coordonner le verrouillage. Si vous prévoyez d'utiliser ce code sur une seule plate-forme, vous pourrez peut-être utiliser Fonction FileLock de NIO . Mais lisez attentivement la documentation et notez que sur de nombreuses plates-formes, le verrou n’est qu’avis.

Une autre approche consiste à faire écrire le fichier par un processus avec un nom que votre processus ne reconnaîtra pas, puis à renommer le fichier en un nom reconnaissable une fois l’écriture terminée. Sur la plupart des plates-formes, l'opération de changement de nom est atomique si la source et la destination sont le même volume de système de fichiers. Le changement de nom peut utiliser une extension de fichier différente ou même déplacer le fichier d'un répertoire à un autre (sur le même volume).

Étant donné que dans ce cas, vous travaillez exclusivement avec XML, la recherche d'une balise de fermeture fonctionnerait, mais ce n'est pas infaillible - que se passe-t-il s'il y a des commentaires après le balisage final, ou le rédacteur, ou si vous n'écrivez tout simplement pas un XML valide? ?

La recherche de la fin de fichier ne fonctionnera pas . Il y aura toujours un EOF, même lorsque l'écrivain vient d'ouvrir le fichier et n'a encore rien écrit. Si ce n’était pas le cas, le plus simple serait de permettre au lecteur de commencer l’analyse dès que le fichier apparaît; il bloquerait simplement jusqu'à ce que l'auteur rédige le dossier. Mais le système de fichiers ne fonctionne pas de cette façon. Chaque fichier a une fin, même si un processus le déplace actuellement.

Autres conseils

De plus, si vous effectuez une vérification suivie d'une écriture, vous avez une condition de concurrence critique. L'état pourrait changer entre le contrôle et l'écriture. Parfois, il est préférable d'essayer de faire ce que vous voulez et de gérer les erreurs avec élégance. peut-être un nouveau mécanisme de nouvelle tentative avec un temps de repli plus long.

Ou redéfinissez votre test. Dans ce cas, vous pourriez peut-être vérifier que la taille du fichier n'a pas changé au cours d'une période antérieure au traitement.

Une autre option consiste à scinder le code en deux. Vous pourriez également avoir un autre thread, peut-être une tâche quartz, chargé de déplacer les fichiers finis dans un répertoire différent de celui traité par votre code principal.

Une chose qui semble fonctionner sous Windows est la suivante. - Créer un objet File () qui représente le fichier en question (en utilisant le constructeur avec le nom de fichier complet) - Créez un deuxième objet File identique, de la même manière. - Essayez firstFile.renameTo (secondFile)

Cet exercice de changement de nom factice semble réussir avec des fichiers qui ne sont pas ouverts pour être édités par une autre application (j'ai testé avec Word), mais échouent s'ils sont ouverts.

Et comme le nw nom de fichier = l'ancien nom de fichier, il ne crée aucun autre travail.

Pour autant que je sache, il n’existe aucun moyen de savoir si un autre processus possède actuellement un descripteur ouvert pour un fichier Java. Une option consiste à utiliser le FileLock classe de nouvelle io. Cela n’est pas pris en charge sur toutes les plates-formes, mais si les fichiers sont locaux et que le processus d’écriture du fichier coopère, cela devrait fonctionner pour toute plate-forme prenant en charge les verrous.

Si vous contrôlez à la fois le lecteur et le rédacteur, une technique de verrouillage potentielle consisterait à créer un répertoire de verrouillage , qui est généralement une opération atomique, pour la durée du processus de lecture et d'écriture. Si vous utilisez ce type d’approche, vous devez gérer l’échec potentiel d’un processus aboutissant à un "processus suspendu". répertoire de verrouillage.

Comme Cheekysoft l’a mentionné, les fichiers ne sont pas atomiques et ne conviennent pas au verrouillage.

Si vous ne contrôlez pas le graveur, par exemple s'il est produit par un démon FTP, la technique du changement de nom ou la technique du délai est la meilleure option.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top