IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

Détecter un fichier en cours de modification


Sujet :

Entrée/Sortie Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur Logiciels et Applications
    Inscrit en
    Juillet 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Logiciels et Applications
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2019
    Messages : 27
    Points : 29
    Points
    29
    Par défaut Détecter un fichier en cours de modification
    Bonjour la communauté,

    Je développe actuellement un module en java qui permet de récupérer des fichiers (image/texte) et de les convertir en ressources.

    Le principe :
    Il y a un répertoire dépôt dans lequel les utilisateurs ajoutent leurs fichier, le programme doit être capable de détecter si un nouveau fichier à été déposé, le récupérer et le convertir en ressource (pour faire simple).

    Mon problème :
    J'aimerai anticiper un cas d'erreur, si mon programme détecte un nouveau fichier, j'aimerai qu'il soit capable de déterminer si le fichier est actuellement en cours de modification (ce qui peut arriver avec un .txt par exemple). Seulement après une petite matinée de recherche je ne trouve pas vraiment de solution viable. J'utilise l'API NIO 2 et WatchService pour développer ce module mais malgré une grosse lecture des explications de JMDoudoux (mon héro ce gars la) et de la plupart des topics de développez.com à ce sujet je n'ai pas trouvé de solution à mon problème.

    Est-ce que quelqu'un par ici aurait un début de solution à proposer ?

    Merci !

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    La notion "en cours de modification" est très relative. Un fichier peut être en cours d'écriture : un flux a été ouvert, tous les octets n'ont pas été encore vidés dans le flux, ou écrits physiquement (l'état qu'on peut connaître d'un fichier n'est pas forcément celui qu'il a réellement à ce moment), et le flux n'est pas fermé. Le système peut prévenir une écriture concurrent, mais pas forcément une lecture concurrente d'un fichier en cours d'écriture. Et un fichier peut être en cours de modification par un utilisateur sans être ouvert, ou sans être verrouillé quand c'est supporté, donc sans être connu du système de fichier comme étant "en cours de modification" au sens qu'un utilisateur est en train de travaille dessus (donc pas forcément qu'il y ait un process qui est en train d'écrire dedans).

    Personnellement, j'ai mis en place des systèmes qui en pratique fonctionnaient assez bien parce que statistiquement, il était peu probable de tomber sur un cas problématique (y compris sur des spools dans lesquels des systèmes automatisés déversaient des fichiers, genre fil de dépêches par exemple (plus ou moins ancêtre des files RSS). Par exemple, pour uploader automatiquement un fichier InDesign ouvert dans Adobe InDesign, donc exclusivement, par une commande relayer via HTTP vers mon application Java depuis un plug-in InDesign, je copiais le fichier le plus rapidement possible, juste un transfert vers un fichier temporaire vers une file physique, et je faisais le traitement sur la copie. Statistiquement, deux sauvegardes successives étaient très rares : dans la mesure où chaque sauvegarde invalidait fonctionnellement le précédent upload, il me suffisait de comparer la taille et la date des deux fichiers (la copie été crée avec la même date que l'origine) pour déterminer que le fichier avait été resauvegardé entre le début et la fin de la copie et je recommençais (j'étais couvert fonctionnellement par un état de retour dans le client qui limitait les sauvegardes successives intempestives, mais il faut aussi compter qu'un utilisateur normal ne sauvegarde que peu souvent relativement au temps qu'il faut pour copier un fichier).

    Pour les spools (ton cas d'ailleurs), je vérifiais à intervalle régulier si le fichier changeait de taille et/ou de date. En te faisant une petite classe/méthode qui encapsule une petite boucle qui vérifie toutes les 100 ms par exemple tu peux un système simple qui fait ça. Attention, pour avoir mis en pratique ce système il y'a une quinzaine d'années, il ne fonctionnait pas sur certains types de montage CIFS/NFS (Mac en particulier), à cause de systèms de cache (il a fallut être en place des systèmes de touch sur les machines distantes pour forcer la mise à jour du cache), mais en local, ça fonctionnait très bien pour les fichiers en cours d'écriture.

    Cependant, des fichiers peuvent être "ouverts" (avec un verrou exclusif posé par une application) sans être nécessairement en cours d'écriture. C'est plutôt rare pour un fichier txt, mais pourquoi pas. S'il y a un verrou exclusif, la bibliothèque Apache Commons fournit la méthode org.apache.commons.io.FileUtils.touch(File), qui tente simplement d'ouvrir un FileWriter sur le fichier.

    Enfin, des fichiers peuvent être ouverts sans pourtant être verrouillé (un fichier texte dans Sublime Text par exemple) : le souci c'est que le fichier peut être ouvert en écriture après que tu commences à le lire. Tu peux utiliser java.nio.channels.FileLock mais il faut savoir que tous les systèmes ne le supportent pas obligatoirement. FileLock peut être utilisé également dans le cas précédent (à la place de, ou en même temps, la multiplication des systèmes permettant de réduire le nombres de cas problématiques).

    Il y a probablement d'autres stratégies, mais globalement tu peux voir qu'il n'y a pas vraiment de solution simple qui fonctionne à 100% sur tous les systèmes, et encore moins dans des environnements hybrides, mais un ensemble de petites solutions qui contribuent ensemble à ce que ça fonctionne la plupart du temps.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur Logiciels et Applications
    Inscrit en
    Juillet 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Logiciels et Applications
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2019
    Messages : 27
    Points : 29
    Points
    29
    Par défaut
    D'accord c'est donc bien plus compliqué que ce que j'imaginais, je pensais trouver une méthode toute prête dans l'API qui permettait ça au départ.

    Du coup je vais opter pour une solution provenant de l'API NIO 2, avec getLastModifiedTime() on peut obtenir la date de la dernière modification, cette méthode étant compatible avec java.time je pourrais probablement créer une variable qui prend 1 min de plus que la date récupérée et récupérer le fichier une fois cette date atteinte, ça laissera une minute au système pour terminer sa modif ce qui devrait être suffisant je pense.

    Sinon j'essaierai de récupérer la date de réception de l’événement MODIFY que me renverra mon WatchKey et tenterai d'utiliser une technique similaire pour laisser le temps au système de terminer son action.

    Je vais approfondir encore mes recherches, ça fait un peu moins de 6 mois que je développe en Java alors c'est pas encore tout à fait naturel pour moi de trouver des solution à mes problèmes.

    Merci en tout cas !

Discussions similaires

  1. [XL-2010] vba-détecter indisponibilité fichier en cours
    Par philppe27 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 31/10/2013, 20h35
  2. Modification d'un fichier en cours de lecture
    Par Dan_121 dans le forum Shell et commandes GNU
    Réponses: 16
    Dernier message: 06/02/2013, 17h44
  3. Empecher Lecture d'Enregistrement en cours de Modification
    Par toony dans le forum Administration
    Réponses: 4
    Dernier message: 09/12/2009, 11h18
  4. [C#][VS2003] Détecter 1 fichier utilisé par un processus
    Par gregos dans le forum Windows Forms
    Réponses: 9
    Dernier message: 17/11/2005, 15h37
  5. Réponses: 2
    Dernier message: 29/01/2004, 11h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo