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 :

Exception après renommage et déplacement d'un fichier


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 Exception après renommage et déplacement d'un fichier
    Bonjour,

    J'ai un problème avec un programme que je développe, je renomme un fichier parce que son nom n'est pas correct et une fois renommé je le déplace dans un autre répertoire.
    Tout se passe bien, le fichier est renommé et déplacé mais je me prends quand même une exception dans la tronche.

    J'utilise l'API WatchService pour détecter un ajout de fichier dans un répertoire, je récupère ce fichier, le traite et l'envoie dans un autre répertoire selon le résultat.

    Je vous file les morceaux de codes qui me posent problème :

    Ici j'utilise une méthode qui vérifie si le nom du fichier est correct, si ce n'est pas le cas, j'utilise une autre méthode qui permet de changer le nom du fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if( checkFileName( filePath ) == false ) {
    		filePath = changeFileName( filePath );
    		fileName = filePath.toString().substring(filePath.toString().lastIndexOf("\\") + 1);
    		//on vérifie si le nom modifié est compatible
    		if( checkFileName( filePath ) == false ) {
    			fileIsOk = false;
    			listOfMessages.add( "nom du fichier incorrect.\n" );
    		}
    	   }
    Code de la méthode de modification du nom :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public Path changeFileName(Path filePath) {
    		Path filePathChanged = filePath;
    		String newFileName;
    		String pathString = filePath.toString();
    		File theFile = new File(pathString);
    		String oldFileName = pathString.substring( pathString.lastIndexOf( "\\" ) + 1 );
    		newFileName = oldFileName.replace( " " , "_" ).replace( "é" , "e" ).replace( "è" , "e" ).replace( "ù" , "u" ).replace( "à" , "a" ).replace( "ç" , "c" );
    		pathString = pathString.replace( oldFileName , newFileName );
    		File theFileRenamed = new File(pathString);
    		theFile.renameTo(theFileRenamed);
    		filePathChanged = stringToPath( pathString );
     
    		return filePathChanged;
    	}
    Code qui pose problème selon moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if( fileIsOk ) {
    		moveFile( filePath, ressourcesPath );
    		//on récupère le fichier déplacé
    		File fileMoved = new File( ressourcesPath.toString() + "\\" + fileName );
    		//on compare la taille du fichier déplacé avec son ancienne taille
    		if( ! ( fileLength == fileMoved.length() ) ) {
    			moveFile(stringToPath(ressourcesPath.toString() + "\\" + fileName), errorPath);
    			listOfMessages.add("la taille du fichiers à été modifiée pendant le transfert.");
    		}
    	}
    L'exception qui est levée est celle ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    java.nio.file.NoSuchFileException: C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect_Name.png
    	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.WindowsFileCopy.move(Unknown Source)
    	at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
    	at java.nio.file.Files.move(Unknown Source)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.moveFile(RessourcesCreator.java:236)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.run(RessourcesCreator.java:104)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreatorMain.main(RessourcesCreatorMain.java:17)
    Je ne comprends pas pourquoi ça plante, tout se passe bien, ça fonctionne comme je veux mais ça merde à la fin et je n'ai aucune idée du pourquoi du comment...
    HELP !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2012
    Messages
    3 020
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2012
    Messages : 3 020
    Points : 16 092
    Points
    16 092
    Par défaut
    Salut,

    ton erreur est là :

    at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.moveFile(RessourcesCreator.java:236)

    et l'erreur c'est que java.nio.file.NoSuchFileException: C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect_Name.png

    le fichier n'est pas trouvé.

    Après, ce qui se passe dans la méthode moveFile() tu ne nous le montre pas, donc c'est difficile de deviner ce qui plante. Mais tu essayes d'accéder à un fichier qui n'existe pas.

  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
    Merci pour ta réponse !

    C'est ce que j'ai cru comprendre oui, mais je comprends pas comment il peut ne pas trouver le fichier...

    Voila le code de la méthode moveFile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public boolean moveFile(Path filePath, Path target) throws IOException {
    		boolean moved = false;
    		//récupération du nom du fichier
    		String fileName = filePath.toString().substring( filePath.toString().lastIndexOf( "\\" ) + 1 );
    		//construction du chemin de destination
    		String targetPath = target.toString() + "\\" + fileName;
    		//déplacement du fichier
    		Files.move( filePath , stringToPath( targetPath.toString() ) );
    		//vérification du déplacement
    		if(fileAlreadyExists( stringToPath( targetPath.toString() ) ) )
    			moved = true;
     
    		return moved;
    	}

  4. #4
    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,

    Tout ce code me semble bien compliqué pour pas grand chose.

    1. Utilise des java.nio.file.Path et c'est tout. Il est rarement nécessaire de les reconvertir en String, sauf pour faire les remplacement de caractères. Il est rarement utile de les convertir en File, sauf si tu utilises par ailleurs des API externes qui sont suffisamment ancienne pour ne pas prendre en charge Path : dans ce cas, pas besoin de repasser par des String, la méthode Path::toFile fait le job. Cela t'évitera d'avoir à faire lastIndexOf("\\") qui ne fonctionnent que sur Windows !
    2. Cela t'évitera aussi de faire des stringToPath( targetPath.toString() ) dont je ne vois pas l'intérêt : convertir un String (targetPath) en String pour le reconvertir en Path. D'une maniètre générale, machin.toString() est inutile si machin est de type String.
    3. Cela t'évitera d'avoir à faire des concaténations de String où tu risques soit d'oublier un séparateur, soit d'en avoir plusieurs qui se succèdent. Les méthodes Path::resolve, Path::relativize, Paths.get()... te permette toutes les manipulations qui vont bien. En plus toutes ces conversions et concaténation de String plombent inutilement les perfs.
    4. Evite de faire des méthodes perso qui ne font qu'appeler une méthode d'une autre API, genre stringToPath qui se peut se faire directement via Paths.get()...
    5. pourquoi faire des trucs du genre if(fileAlreadyExists( stringToPath( targetPath.toString() ) ) ) pour détecter que le fichier a bien été déplacé.
      1. la méthode Files.move() fonctionne suffisamment bien pour que tu lui fasses confiance : si le fichier n'est pas déplacé, tu auras une exception. Si pas d'exception, alors le fichier est déplacé.
      2. on teste toujours le retour de File::renameTo car cette méthode ne retourne pas d'exception si le fichier n'a pas été déplacé, mais false. Une raison déjà pour préférer les Path et Files.move().
    6. Pour le remplacement des caractères accentués et le c cédille, où tu en traites que quelqu'uns, je sais pas j'ai pas compté, mais même pas 5 % à vue de nez par newFileName = oldFileName.replace( " " , "_" ).replace( "é" , "e" ).replace( "è" , "e" ).replace( "ù" , "u" ).replace( "à" , "a" ).replace( "ç" , "c" ); (et oui, parce qu'il y a aussi, ê, ë, ï, î, ô, et d'autres moins usités certes, mais qui existent quand même), tu peux utiliser un Normalizer :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      public static Path normalize(Path path) {
      	return Paths.get(normalize(path.toString()));
      }
       
      public static String normalize(String s) {
      	return Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[\\p{InCombiningDiacriticalMarks}]", "")
                               .replace(' ', '_');
      }
    7. Il est inutile de renommer et déplacer. Déplacer, c'est renommer, et vice-versa. Les deux peuvent être faits en même temps. En revanche, un déplacement ne peut être fait qu'au sein d'une partition. Il faut éventuellement en ternir compte pour un déplacement qui implique un changement de disque, pour lequel il faudra copier et supprimer l'original.
    8. C'est quoi l'intérêt du test qui vérifie si la taille a changé pendant le transfert ? Si la taille a changé, c'est que ça a planté en plein transfert, donc qu'il y a une exception, donc qu'on n'exécutera jamais ce code. En revanche, il peut arriver que les tailles ne soient pas exactement les mêmes s'il y a des montages distants dans l'histoire : parfois, le fichier distant a changer, mais l'accès distant ne le "sait" pas encore. Avec smb, un fichier pourtant non vide peut avoir une taille de 0.


    Tu auras un code beaucoup plus court et simple et donc plus facile à débogguer. Et beaucoup plus facile à lire pour tout le monde.


    Pour ton cas d'erreur, comment est déterminé la liste des fichiers à traiter. As-tu penser qu'après une exécution jusqu'au bout, un jeu de test est différent de celui de départ (des fichiers ont été déplacés). Ensuite, en ajoutant des traces ici ou là, tu pourras voir ce qu'il fait exactement, quels fichiers sont traités, déplacés où et quand, et tu devrais voir s'il est normal pas ou que ce fichier en erreur soit traité, ou pourquoi il n'existe plus lorsqu'il est traité.
    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.

  5. #5
    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
    Bonjour,

    Déjà merci pour ta réponse, ça m'aide beaucoup, vraiment.

    J'ai suivi la plupart de tes conseils, j'ai mis des traces à peu près partout où j'en avais besoin, supprimé les méthodes qui utilisaient simplement l'API en elle même, installé le normalizer comme tu me l'a conseillé et utilisé des resolves et des get à la place de mes String à tire larigot.

    Pour le point n°5 si je fais ça c'est uniquement pour mon test unitaire, je voulais que la méthode me renvoie vrai ou faux pour la tester.

    Alors maintenant j'ai un nouveau problème, j'essaie de déplacer et renommer le fichier en même temps comme tu me l'a conseillé mais je n'y parviens pas... Dans ce cas, le Path à l'air d'avoir été modifié mais il ne trouve pas le fichier.

    On part du principe que fileIsOk est à true :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if( fileIsOk ) {
    			if( checkFileName( filePath ) == false ) {
    				System.out.println("Envoi du fichier dans ressources.");
    				moveFile(normalize(filePath), ressourcesPath);
    			}
    			else {
    				System.out.println("Envoi du fichier dans ressources.");
    				System.out.println(filePath);
    				moveFile( filePath, ressourcesPath );
    			}
    		}
    méthode moveFile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public boolean moveFile(Path filePath, Path target) throws IOException {
    		boolean moved = false;
    		//récupération du nom du fichier
    		String fileName = filePath.getFileName().toString();
    		//construction du chemin de destination
    		Path targetPath = target.resolve(fileName);
    		//déplacement du fichier
    		Files.move( filePath , targetPath );
    		//vérification du déplacement
    		if(Files.exists( targetPath ) )
    			moved = true;
     
    		return moved;
    	}
    et enfin l'erreur que j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    java.nio.file.NoSuchFileException: C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect_Name.png
    	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.WindowsFileCopy.move(Unknown Source)
    	at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
    	at java.nio.file.Files.move(Unknown Source)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.moveFile(RessourcesCreator.java:209)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.run(RessourcesCreator.java:97)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreatorMain.main(RessourcesCreatorMain.java:17)
    Sinon j'ai aussi essayé de renommer puis de déplacer, mais la par contre je ne comprends pas grand chose, le fichier semble être renommé mais puisque je vois son nom changer quand je fais la manip' du glisser/déposer mais dans l'erreur qui m'est renvoyée et les traces il n'y a aucun signe de changement de nom...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    if( fileIsOk ) {
    			if( checkFileName( filePath ) == false ) {
    				System.out.println("Nom de fichier incorect, renommage :");
    				System.out.println("	Avant : "+filePath);
    				filePath = changeFileName(filePath);
    				System.out.println("	Après : "+filePath);
    				System.out.println("Envoi du fichier dans ressources.");
    				moveFile(filePath, ressourcesPath);
    			}
    			else {
    				System.out.println("Envoi du fichier dans ressources.");
    				System.out.println(filePath);
    				moveFile( filePath, ressourcesPath );
    			}
    		}
    La méthode changeFileName :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public Path changeFileName(Path filePath) throws IOException {
    		System.out.println(filePath);
    		Path renamedFilePath = normalize(filePath);
    		Files.move(filePath, renamedFilePath);
    		System.out.println(filePath);
     
    		return filePath;
    	}
    Voici les traces et l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Nom de fichier incorect, renommage :
    	Avant : C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    	Après : C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    Envoi du fichier dans ressources.
    source : C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    dest : C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\ressources\incorect Name.png
     
    java.nio.file.NoSuchFileException: C:\Users\rfontaine\eclipse-workspace\RessourcesCreatorV0\deposit\incorect Name.png
    	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.WindowsFileCopy.move(Unknown Source)
    	at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
    	at java.nio.file.Files.move(Unknown Source)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.moveFile(RessourcesCreator.java:211)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreator.run(RessourcesCreator.java:97)
    	at com.absyss.vbam.ressourcescreator.v0.RessourcesCreatorMain.main(RessourcesCreatorMain.java:17)
    Si tu as une idée, tu m'a déjà beaucoup aidé et je t'en remercie ^^

  6. #6
    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
    C'est bon ! J'ai trouvé la solution !

    En fait il ne fallait pas que je move mon fichier dans ressources dès que je l'avais renommé, parce que cela générai un ENTRY_CREATE et on repassait dans le répertoire dépôt alors que le fichier n'y était plus, du coup j'ai simplement viré le move de la condition de renommage, ce qui fait qu'au deuxième passage, on cherchait le fichier dans le dépôt avec le bon nom, on ne repassait pas par le renommage et le transfert se faisait correctement !

    En tout cas merci pour l'aide, tout est nickel désormais, et je ressors avec un code plus propre et plus lisible !

  7. #7
    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
    Juste deux dernières questions avant de mettre le sujet en résolu, comment est-ce que je peux procéder pour l'éventualité que des tirets ou autre caractères soient dans le nom d'un fichier ?

    Le normalizer permet de virer les diacritiques mais pas les autres caractères d'après ce que j'ai compris.

    Et ensuite est-ce qu'il est possible d'utiliser le normalizer pour détecter si le nom est correct ?

    EDIT : j'ai trouvé c'est bon !

    voici le code au cas où :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public boolean checkFileName(Path filePath) {
    		boolean validName = false;
    		String fileName = filePath.getFileName().toString();
    		String fileNameReference = normalize(fileName);
    		if( fileName.equals(fileNameReference) )
    			validName = true;
     
    		return validName;
    	}
    Merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fichier introuvable apres renommage servlet
    Par Didee71 dans le forum Eclipse Platform
    Réponses: 1
    Dernier message: 17/02/2008, 13h18
  2. erreur après renommage d'une fonction
    Par Ndugu dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 21/11/2006, 09h08
  3. Copie ou déplacement d'un fichier
    Par Tchaill39 dans le forum Delphi
    Réponses: 4
    Dernier message: 30/10/2006, 14h36
  4. Réponses: 2
    Dernier message: 29/05/2006, 09h54
  5. Réponses: 4
    Dernier message: 19/05/2006, 17h06

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