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

Langage Java Discussion :

Ma String est-elle compatible Latin1 ?


Sujet :

Langage Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut Ma String est-elle compatible Latin1 ?
    Bonsoir,

    comment puis-je tester si les différents caractères contenus dans ma chaine de caractères font bien partis de la table ISO-8859-1 (latin1) ?

    Avant de stocker une chaine de caractères dans une base de données dont le charset est défini sur latin1, comment puis-je m'assurer que ma chaîne de caractères ne comportent pas des caractères qui ne peuvent pas être conservés ?

    Merci pour votre réponse,
    F.

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Tu peux utiliser les CharsetEncoder et la méthode canEncode() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	String str = ...
     
    	CharsetEncoder encoder = Charset.forName("iso-8859-1").newEncoder();
    	boolean ok = encoder.canEncode(str);
    a++

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut
    Merci beaucoup pour ta réponse.
    Super

    F.

  4. #4
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Mmmm, ca me paraît pas correct....

    Si je fais ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    		CharsetEncoder iso8859Encoder = Charset.forName("iso-8859-1")
    				.newEncoder();
    		CharsetEncoder utf8Encoder = Charset.forName("UTF-8").newEncoder();
     
    		String s = "éàü";
     
    		String utf8S = new String(utf8Encoder.encode(
    				CharBuffer.wrap(s.toCharArray())).array());
     
    		System.out.println(utf8S);
     
    		System.out.println(iso8859Encoder.canEncode(utf8S));
    Le code retourne true alors que la chaine est UTF-8.

  5. #5
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Tommy31 Voir le message
    Le code retourne true alors que la chaine est UTF-8.
    La chaine n'est pas en UTF-8 !!!

    En interne en Java toutes les Strings sont encodés en UTF-16 :
    A String represents a string in the UTF-16 format
    Tout comme les char/Character d'ailleurs :
    The Java 2 platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes

    Donc c'est une erreur de dire qu'une String utilise un encodage quelconque.






    Ce n'est que lors des opérations d'entrées/sorties que l'on utilise un encodage (conversion vers des bytes, fichiers, BD, ...), et là on a alors en fait une conversion UTF-16<->encodage désiré...




    Donc ici ta chaine "éàü" comporte trois caractères qui sont parfaitement encodable en iso-latin1...


    Maintenant si tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	String str = "1€";
     
    	CharsetEncoder encoder = Charset.forName("iso-8859-1").newEncoder();
    	boolean ok = encoder.canEncode(str);
    Tu obtiendras un joli "false" car le caractère "€" n'est pas représentable dans iso-8859-1...


    a++

  6. #6
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Mmm, tjs pas d'accord.

    Cette chaîne "éàü" lorsque je l'affecte à ma string est stockée selon un encodage utf-16. Ca d'accord.

    Mais lorsque j'écris ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String utf8S = new String(utf8Encoder.encode(
    				CharBuffer.wrap(s.toCharArray())).array());
    Ma chaîne est encodé UTF-8, c'est à dire que les octets composant la chaîne se conforment au nouvel encodage. On peut s'en assurer en écrivant le train d'octet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                   for (Byte b : utf8S.getBytes()) {
    			System.out.println(b);
    		}
    Par contre pour ton code, ok. En fait la question portait sur savoir s'il y avait des caractères non encodables. Auquel cas ta solution est bonne

    Moi j'étais parti sur l'idée de savoir si la chaîne soumise était encodée en iso ou pas. Or lorsque la chaîne soumise est sous un encodage dont le jeu de caractère est un sous-ensemble de iso-8859-1, ta méthode ne le décelais pas.

    Bon bon, donc right answer...

  7. #7
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    En même temps ça m'étonnait que tu te sois planté...

  8. #8
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Ta chaine n'est pas encodé en UTF8 mais "n'importe comment" !

    D'ailleurs si tu l'affiches dans la console ou un composant Swing tu obtiendra n'importe quoi...



    C'est une erreur typique que de croire qu'une String est associé à un encodage. Comme je l'ai dit les String sont toujours représenté en UTF16. Par contre lorsqu'on manipule des fichiers on lit des bytes qui peuvent représenter une


    Citation Envoyé par Tommy31 Voir le message
    Mais lorsque j'écris ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String utf8S = new String(utf8Encoder.encode(
    				CharBuffer.wrap(s.toCharArray())).array());
    Ma chaîne est encodé UTF-8, c'est à dire que les octets composant la chaîne se conforment au nouvel encodage.
    En décomposant ton code on obtient ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	String s = "éàü";
    	char[] array = s.toCharArray();
    	CharBuffer charBuffer = CharBuffer.wrap(s.toCharArray());
     
    	ByteBuffer byteBuffer = utf8Encoder.encode(charBuffer);
    	byte[] bytes = byteBuffer.array();
     
    	String utf8S = new String(bytes);
    Je pense que tu es d'accord avec moi pour dire que les trois premières lignes ne changent en rien le contenu : ce n'est qu'une conversion de type mais les caractères sont toujours représenté de la même manière.

    La ligne la plus intérressante concerne l'appel à encode(), qui transforme un CharBuffer (en UTF-16 donc) vers un ByteBuffer (en UTF-8).

    Enfin tu fais new String(bytes), avec bytes qui représentent donc un texte encodé en UTF-8, qui devrait refaire l'opération inverse (de UTF-8 vers UTF-16).

    Or si on regarde la javadoc de String(byte[]), on peut lire ceci :
    Constructs a new String by decoding the specified array of bytes using the platform's default charset.
    bytes est donc interprété selon l'encodage par défaut. Donc cela donnera n'importe quoi a moins que ton système utilise l'UTF-8 (c'est assez courant sous Linux).

    Par exemple sous Windows cela revient à faire une conversion de windows-1252 vers UTF-16 en prenant en entrée de l'UTF-8






    Donc a se noter en gros quelque part : En Java il est abbérant de vouloir changer l'encodage d'une String !
    Les String sont encodé en UTF-16 point barre !



    Les autres encodages sont utilisés uniquement pour les communications "en dehors", par exemple vers un fichier, une base de données...



    a++

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut
    Merci à tous pour votre réponse.

    La réponse suivante me convient parfaitement : «

    Maintenant si tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    	String str = "1€";
     
    	CharsetEncoder encoder = Charset.forName("iso-8859-1").newEncoder();
    	boolean ok = encoder.canEncode(str);
     
    Tu obtiendras un joli "false" car le caractère "€" n'est pas représentable dans iso-8859-1...
     
    a++
    ».

  10. #10
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Ta chaine n'est pas encodé en UTF8 mais "n'importe comment" !

    D'ailleurs si tu l'affiches dans la console ou un composant Swing tu obtiendra n'importe quoi...

    Bonjour, j'aimerai savoir comment faire pour afficher une string correctement dans un composant swing et ce peut importe le systeme sur lequel je suis (windows/linux) car je n'ai pas saisi tout ce qui a été dit.

    merci pour votre aide
    Tchû

  11. #11
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Il n'y a rien de particulier à faire pour afficher correctement une String dans un composant Swing.


    Si tu as un problème d'affichage cela vient de ta chaine qui est mal lu, par exemple si elle provient d'un fichier encodé en UTF8 que tu lirais comme un fichier iso-latin1...


    a++

  12. #12
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    en fait je t'expose mon probleme:

    je lis une string dans un fichier et je l'affiche dans un composant swing.

    le probleme c'est que suivant l'OS, l'affichage déconne (windows principalement).

    j'utilise un bufferedReader et j'utilise la methode readline() qui renvoie une string.

    Est-ce une mauvaise maniere pour ce que je dois faire ?

    si tel est le cas que me conseille tu ?

    merci
    Tchû

  13. #13
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Quel est l'encodage du fichier ?

    BufferedReader n'est pas un problème, par contre il faut préciser l'encodage que tu utilises pour la lecture !


    Avec new FileReader("fichier") tu utilises l'encodage par défaut du système, et tu as donc un comportement aléatoire selon le système : si l'encodage par défaut du système est le même que celui du fichier tout fonctionnera correctement, sinon tu auras des caractères invalides !


    Tu dois donc spécifier l'encodage du fichier, et pour cela utiliser directement InputStreamReader à la place, car malheureusement Sun n'a jamais intégré la gestion de l'encodage au niveau des FileReader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Pour lire un fichier en UTF8 :
    new InputStreamReader(new FileInputStream("fichier"), "utf8")

    A la rigueur tu pourrais te faire ton propre FileReader en rajoutant les constructeurs qui spécifie l'encodage :
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    class MyFileReader extends InputStreamReader {
     
    	/**
             * Creates a new <tt>FileReader</tt>, given the name of the file to read
             * from.
             * 
             * @param fileName
             *            the name of the file to read from
             * @exception FileNotFoundException
             *                if the named file does not exist, is a directory rather
             *                than a regular file, or for some other reason cannot be
             *                opened for reading.
             */
    	public MyFileReader(String fileName) throws FileNotFoundException {
    		super(new FileInputStream(fileName));
    	}
     
    	public MyFileReader(String fileName, Charset charset)
    			throws FileNotFoundException {
    		super(new FileInputStream(fileName), charset);
    	}
     
    	public MyFileReader(String fileName, String charsetName)
    			throws FileNotFoundException, UnsupportedCharsetException {
    		this(fileName, Charset.forName(charsetName));
    	}
     
    	/**
             * Creates a new <tt>FileReader</tt>, given the <tt>File</tt> to read
             * from.
             * 
             * @param file
             *            the <tt>File</tt> to read from
             * @exception FileNotFoundException
             *                if the file does not exist, is a directory rather than a
             *                regular file, or for some other reason cannot be opened
             *                for reading.
             */
    	public MyFileReader(File file) throws FileNotFoundException {
    		super(new FileInputStream(file));
    	}
     
    	public MyFileReader(File file, Charset charset)
    			throws FileNotFoundException {
    		super(new FileInputStream(file), charset);
    	}
     
    	public MyFileReader(File file, String charsetName)
    			throws FileNotFoundException, UnsupportedCharsetException {
    		this(file, Charset.forName(charsetName));
    	}
     
    	/**
             * Creates a new <tt>FileReader</tt>, given the <tt>FileDescriptor</tt>
             * to read from.
             * 
             * @param fd
             *            the FileDescriptor to read from
             */
    	public MyFileReader(FileDescriptor fd) {
    		super(new FileInputStream(fd));
    	}
     
    	public MyFileReader(FileDescriptor fd, Charset charset)
    			throws FileNotFoundException {
    		super(new FileInputStream(fd), charset);
    	}
     
    	public MyFileReader(FileDescriptor fd, String charsetName)
    			throws FileNotFoundException, UnsupportedCharsetException {
    		this(fd, Charset.forName(charsetName));
    	}
    }



    Maintenant si tu ne connais pas à l'avance l'encodage de ton fichier c'est plus complexe. Je sais qu'il existe des APIs (externes) permettant de le détecter mais j'ignore comment elles fonctionnent...


    a++

  14. #14
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    ok je te remercie, je vais regarder ça, et pour l'encodage du fichier je vais me débrouiller

    merci encore
    Tchû

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut
    plus simple : utiliser l'API commons-io d'Apache :

    De mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FileUtils.readFileToString(File, "UTF-8");
    FileUtils.writeStringToFile(File, String, "UTF-8");

  16. #16
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    Salut adiguba,

    j'ai une autre question, voici comment je dois "matcher" mon fichier :

    ligne1
    ligne2
    ligne3
    ligne4

    et je dois extraire les lignes une par une, et je crois que le inputFileReader ne peut faire cela (il se peut que je me trompe)

    pour info : j'ai trouvé l'encodage: c'est du utf-8

    merci encore pour ton aide
    Tchû

  17. #17
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    si je me suis mal fait comprendre dites-le moi que je réexplique
    Tchû

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut
    Comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    String str = "...";
    String[] tab = str.split("\n");
     
    for(int i = 0; i < tab.length; i++) {
    String ligne = tab[i];
    }

  19. #19
    Membre du Club Avatar de daronmaster
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 67
    Points : 56
    Points
    56
    Par défaut
    ok pour la méthode split (je ne la connaissai pas) mais comment obtenir une string à partir de mon InputStreamReader ?

    je préfère me répéter afin que vous n'ayez pas à revenir en arrière(page précédente) :

    mon pb : je dois extraire ces lignes d'un fichier encodé en utf-8 afin de pouvoir à les incorporer à un composant swing sans avoir de probleme d'affichage (notamment les accents) sur les plateforme où le logiciel sera executé (Windows, linux ...)
    Tchû

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 87
    Points : 170
    Points
    170

Discussions similaires

  1. Ma configuration est-elle compatible
    Par Roitiflamme dans le forum Windows 8
    Réponses: 4
    Dernier message: 07/01/2013, 20h37
  2. "string" est-elle de type char*
    Par yessine66 dans le forum C
    Réponses: 2
    Dernier message: 30/09/2010, 18h33
  3. Réponses: 6
    Dernier message: 31/10/2006, 10h55
  4. Réponses: 7
    Dernier message: 11/09/2006, 16h44
  5. La fonction fgets est-elle compatible Windows/Unix ?
    Par ashurai dans le forum Langage
    Réponses: 1
    Dernier message: 05/04/2006, 17h59

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