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

Java Discussion :

Problème encodage File#getName


Sujet :

Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut Problème encodage File#getName
    Bonjour à tous,

    Je ne parviens pas à encoder correctement les accents dans les noms de fichier/répertoire sur un système Windows (pas encore testé sous X).

    Voici ce que j'obtiens quand j'encode mes noms de fichier :
    La réforme managériale et sécuritaire de l’école.pdf
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    protected String encode(String value) {
    	try {
    //		byte[] ansiBytes = new Base64().decode(value.getBytes());
    		byte[] ansiBytes = value.getBytes();
    		String unicode = new String(ansiBytes, "windows-1252");      // Cp1252
    		byte[] utfBytes = unicode.getBytes("UTF-8");
    		return new String(utfBytes);
     
    	} catch (UnsupportedEncodingException e) {
    		logger.debug("Erreur de décodage", e);
    		return value;
    	}
    }
    Je fais certainement quelque chose à l'envers... mais quoi ?
    Merci d'avance pur vos lumières.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Le code que tu donnes ne veut rien dire : tu fais des transformations bizarroïdes qui ne donneront rien de bon !


    Une String n'est pas associé à un encodage. Elle utilise toujours l'UTF-16, donc tu n'as pas à l'encoder !

    Soit elle est correct et tu l'utilises directement.
    Soit elle ne l'est pas et le problème se trouve avant...


    Bref ta méthode encode() ne sert à rien, au contraire il se pourrait que ce soit la source de ton problème

    a++

  3. #3
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Effectivement, c'est lorsque j'écris cette String dans un fichier XML (UTF-8) que les caractères sont abimés. J'essaye de palier ce pb en passant de UTF-16 à UTF-8 sans heurs.
    Après, je suis un peu parti en vrille sur d'autres encodages, n'étant pas parvenu à mes fins sur la base de l'algorithme ci-dessus...

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Pas besoin de bidouiller comme cela. Il suffit de préciser l'encodage à l'ouverture du fichier.

    Montres ton code et on pourra t'aider; )


    a++

  5. #5
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Voici le code d'écriture. Le fichier est ouvert par d'autres applications, je ne pense pas que ça soit un problème de lecture dans mon code Java.

    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
    20
    21
    22
    private static DocumentBuilder db;
    static {
    	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    	dbf.setIgnoringElementContentWhitespace(true);
    	try {
    		db = dbf.newDocumentBuilder();
    	} catch (ParserConfigurationException e) {
    		e.printStackTrace();
    	}
    }
    ...
    Document xmlDoc = db.newDocument();
    ...
    try {
    	// cf. http://java.developpez.com/faq/xml/?page=dom#XML_DOM_to_string
    	TransformerFactory transFactory = TransformerFactory.newInstance();
    	Transformer transformer = transFactory.newTransformer();
    	transformer.transform(new DOMSource(xmlDoc), new StreamResult(target));
    } catch (TransformerException e) {
    	logger.fatal("Erreur d'écriture du document : " + target.getPath(), e);
    	System.exit(1);
    }
    Je précise que mon Workspace est déclaré en UTF-8 et que je lance mon application avec le paramètre JVM -Dfile.encoding=UTF8.

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tooms4444 Voir le message
    Je précise que mon Workspace est déclaré en UTF-8 et que je lance mon application avec le paramètre JVM -Dfile.encoding=UTF8.
    Il est préférable de préciser l'encodage dans le code source plutôt que de redéfinir file.encoding (ce qui pourrait avoir des effets néfastes).


    Quel est le type de target ? java.io.File ?
    Dans ce cas il est préférable d'ouvrir explicitement un InputStreamReader afin de préciser l'encodage...


    Enfin il faudrait voir comment tu construis ton document avec DocumentBuilder... Le problème pourrait se situer à ce niveau.



    Un seul petit défaut d'encodage peut te pourrir tout un code


    a++

    PS : hors-sujet mais... pourquoi ton DocumentBuilder est en static ????

  7. #7
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Un seul petit défaut d'encodage peut te pourrir tout un code
    Oooooh oui !

    PS : hors-sujet mais... pourquoi ton DocumentBuilder est en static ????
    Il est pas bien là ? Bon, réflexe de web dev, je suppose...

  8. #8
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Quel est le type de target ? java.io.File ?
    Dans ce cas il est préférable d'ouvrir explicitement un InputStreamReader afin de préciser l'encodage...
    Yep. mais où dois-je "placer" un InputStreamReader, STP ?? J'ai un arbre DOM et un fichier de sortie (output), non ?
    Est-ce que je peux jouer sur le DOMSource ?

  9. #9
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Enfin il faudrait voir comment tu construis ton document avec DocumentBuilder
    => via le Document : createElement, setAttribute, appendChild, etc.
    Lorsque j'analyse les nœuds en debug avant l'écriture, les chaînes sont correctement encodées. Je n'ai pas remarqué de paramétrage d'encoding sur ce monteur.

  10. #10
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Writer out = new OutputStreamWriter( new FileOutputStream(target), "UTF-8");
    try {
        transformer.transform(new DOMSource(xmlDoc), new StreamResult(out));
    } finally {
        out.close();
    }

    a++

    PS : Le DocumentBuilder est utilisé pour créer un document, donc ce devrait être une variable locale. Cela ne sert à rien de le conserver pendant toute la durée de vie de l'application...

  11. #11
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Le DocumentBuilder est utilisé pour créer un document, donc ce devrait être une variable locale. Cela ne sert à rien de le conserver pendant toute la durée de vie de l'application
    C'est VRAI. SI le traitement n'est exécuté qu'une seule fois. Comme par exemple dans une servlet ou un daemon

    RAS du côté de l'encodage avec OutputStreamWriter+UTF8

  12. #12
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 592
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 592
    Par défaut
    En réalité, le coup du Writer n'est pas la bonne méthode : en effet le Transformer va vouloir générer une déclaration xml du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?xml version="1.0" encoding="utf-8"?>
    Or, il n'a aucun moyen de demander au Writer en quel encodage il va vraiment écrire les caractères qu'il lui envoie. Cette déclaration a donc de bonnes chances d'indiquer n'importe quoi.

    Pour indiquer en quel encodage on veut produire les document XML, on lui spécifie bien un File ou un OutputStream.
    Mais on configure le Transformer pour lui indiquer l'encodage de sortie souhaité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Désolé, déjà (ré)essayé. RAS. C'est d'ailleurs l'encoding par défaut normalement produit par le transformer.

    En plus, j'omets la déclaration XML, par soucis de compatibilité externe (je produis un format FreeMind 0.9.0 pour ne pas le nommer).
    J'ai même essayé de mettre en UTF-16, pour voir, mais l'application externe (FreePlane) a refusé de le lire.

  14. #14
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 592
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 592
    Par défaut
    RAS ça veut dire Rien À Signaler. C'est ce qu'on dit quand tout va bien et qu'il n'y a pas de problème -_-°.

    En plus, j'omets le header XML, par soucis de compatibilité externe (je produis un format FreeMind 0.9.0 pour ne pas le nommer).
    FreeMind n'a pas le moindre problème pour lire les déclarations XML. Mais bon, si vraiment tu ne produits pas de déclaration XML (comment est-ce possible ? Ça ne se voit pas dans ton code !), alors dans ce cas la méthode à base de Writer est censée marcher (avec l'implémentation XML fournie par défaut avec Java, en tout cas).

    Voici un miniprogramme qui prouve que ça marche parfaitement :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class LolXmlTest {
     
      public static void main(String[] args) throws Exception {
        // À modifier à loisir
        File outFile = new File("c:/lolxml.xml");
        String rootContent = "Été sur une île";
     
        // Créer le doc
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbFactory.newDocumentBuilder();
        Document doc = builder.newDocument();
     
        // remplir le doc
        Element root = doc.createElement("root");
        doc.appendChild(root);
        root.appendChild(doc.createTextNode(rootContent));
     
        // créer le Transformer
        TransformerFactory transformFactory = TransformerFactory.newInstance();
        Transformer transformer = transformFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
     
        // générer le fichier
        transformer.transform(new DOMSource(doc), new StreamResult(outFile));
      }
     
    }
    Si ça fait encore des erreurs d'accents, vérifie avec un débuggeur que la String rootContent n'a pas d'erreur d'accent. Si oui, c'est que ton compilateur se trompe sur l'encodage de tes fichiers source *.java

    Si tu as des erreurs d'accents, mais pas dans rootContent, deux possibilités :
    - les programmes dont tu te sers pour vérifier le format produit, ne savent pas reconnaître de l'utf-8.
    - ton environnement est configuré pour utiliser une autre implémentation de XML que celle livrée avec Java par défaut, et cette implémentation est bugguée pour la gestion des encodages. Je n'en ai jamais rencontré.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    OK... le test proposé a fait des bulles (Champagne) : RAS (ça marche) !
    En ouvrant le fichier XML avec Notepad++, les caractères sont en place.

    Alors j'ai remis l'encoding dans le transformer : bingo ! Lorsque j'ai ouvert le fichier produit avec Nodepad++, les caractères étaient en place. MERCI !

    MAIS FreePlane affiche tj des caractères spéciaux... Alors j'ai ouvert le fichier XML avec XmlShell, et l'éditeur a montré des caractère encodés sous la forme #1234 ; sous vi (Cygwin) les caractères s'affichent correctement.

    FreeMind/FreePlane n'a pas le moindre problème pour lire les déclarations XML
    C'est juste, mais le format produit par FreePlane n'en contient pas. Je ne fais que le constater ; cela n'a pas l'air d'avoir d'importance (et c'est bien normal).

  16. #16
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut Ah Ah...
    J'ai un fichier produit directement par FreePlane... Notepad++ indique qu'il est encodé... en ANSI !
    Tandis que le fichier produit par mon application Java est bien indiqué comme étant codé en UTF-8 (sans BOM).

    C'est là qu'est l'os, j'imagine ! Quelqu'un sait-il quoi mettre en encoding du transformer pour coder en ANSI, SVP ?

  17. #17
    Membre éclairé
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Par défaut
    Bon, ben voilà, fin de l'histoire : j'ai mis "ISO-8859-1" et FreePlane fonctionne correctement...

    J'AIME BIEN QUAND LES FICHIERS XML CONTIENNENT UNE DÉCLARATION, CA ÉVITE LES MALENTENDUS...
    Désolé de crier, ça soulage !

    Merci encore à vous pour votre aide (plus que) patiente.

  18. #18
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 592
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 592
    Par défaut
    Citation Envoyé par tooms4444 Voir le message
    Quelqu'un sait-il quoi mettre en encoding du transformer pour coder en ANSI, SVP ?
    Quand Notepad++ parle d'encodage ANSI, c'est un abus de langage pour dire "l'encodage 8-bit utilisé par défaut sur les machines Windows occidentales," généralement nommé Codepage 1252, et dont le nom IANA est windows-1252.

    Donc mettre "windows-1252" à la place de "utf-8".

    Note : bien qu'en pratique il soit toujours géré, Java ne garantit pas de gérer cet encodage-là. On peut préférer utiliser "iso-8859-1", qui est très semblable, garanti, et utilisera des entités caractère XML pour les caractères qu'il ne gère pas, comme le œ et le €. C'est moins beau à l'œil nu mais ça marche très bien aussi.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  19. #19
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 592
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 592
    Par défaut
    Citation Envoyé par tooms4444 Voir le message
    J'AIME BIEN QUAND LES FICHIERS XML CONTIENNENT UNE DÉCLARATION, CA ÉVITE LES MALENTENDUS...
    D'autant plus qu'en principe, XML exige que pas de déclaration => utf-8 ou utf-16, et rien d'autre.
    Sauf protocole pré-établi indiquant le contraire, et bien sûr, tout le monde se figure être un protocole pré-établi.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/09/2006, 20h20
  2. problème require_once('file.php') avec 2 repertoires.
    Par vacknov dans le forum Langage
    Réponses: 5
    Dernier message: 22/08/2006, 16h35
  3. [DOM] Problème encodage
    Par spilliaert dans le forum Format d'échange (XML, JSON...)
    Réponses: 19
    Dernier message: 05/06/2006, 16h26
  4. Probléme encodage caractéres spéciaux MYSQL
    Par FoxLeRenard dans le forum Installation
    Réponses: 1
    Dernier message: 20/02/2006, 12h10
  5. Réponses: 1
    Dernier message: 02/02/2006, 23h12

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