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

VB.NET Discussion :

fichiers textes : choix de l'encodage


Sujet :

VB.NET

  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut fichiers textes : choix de l'encodage
    Bonjour à tous,

    Histoire de planter le décor, voici en gros la situation dans laquelle je me trouve.

    J'ai un fichier texte comprenant des données exportées d'un système tiers.
    Je lis ce fichier ligne par ligne (chaque ligne étant un record) et j'importe les données dans une DB Sql Server.
    Lorsqu'il y a quelque chose qui coince sur une des lignes, je copie la ligne dans un fichier créé à la volée et j'y ajoute le message d'erreur (une sorte de fichier log quoi).

    Mon souci est que l'encodage de mon fichier source est différent de celui du fichier de destination (celui pour le log). Ce qui fait que j'ai des soucis avec les caractères accentués.

    Mon fichier log est créé comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Using sw As StreamWriter = IO.File.CreateText(LePathQuiVaBien)
       sw.WriteLine(LeMessage)
    End Using
    Si j'ouvre chacun des deux fichiers avec Notepad++, je constate que le première est encodé en ANSI et le second en UTF-8.

    Faut-il que je précise lors de la déclaration de mon streamreader l'encodage utilisé ou bien dois-je préciser cela pour le streamwriter ?

    Je note cependant que dans la DB, les caractères accentués y sont bien représenté. VS ne semble donc pas avoir de problème pour arriver à les lire correctement.

    EDIT : Je suis en train de tester en spécifiant l'encodage ASCII à la déclaration du streamreader. J'en déduirai si cela fonctionne que c'est là la bonne méthode à appliquer. Cependant, si quelqu'un pouvait m'apporter quelques explications théoriques sur le sujet, cela ne serait pas de refus.

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Bon et bien ça ne marche pas...

    Maintenant j'ai un point d'interrogation à la place d'un carré dans le fichier log XD.

    Help please

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 067
    Par défaut
    Tu as la possibilité de choisir l'encodage dans ton streamwriter

    http://msdn.microsoft.com/fr-fr/libr...=VS.80%29.aspx

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Lors de la lecture de ton fichier source, les fonctions par défaut (File.ReadAllLines, etc), présument que la source est encodée en UTF-8 ou UTF-32 (et détectent automatiquement un besoin pour UTF-32). C'est là que ça coince, tu dois spécifier l'encodage ANSI de la source à la lecture de celle-ci.

    L'encodage par définition pour l'enregistrement est déjà UTF-8 par défaut.

    Note que les strings en mémoire ont un encodage Unicode UTF-16 : donc il y aura les conversions suivantes: ANSI (source) -> UTF-16 (mémoire) -> UTF-8 (destination).

  5. #5
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Lors de la lecture de ton fichier source, les fonctions par défaut (File.ReadAllLines, etc), présument que la source est encodée en UTF-8 ou UTF-32 (et détectent automatiquement un besoin pour UTF-32). C'est là que ça coince, tu dois spécifier l'encodage ANSI de la source à la lecture de celle-ci. Actuellement, ta string en mémoire a un encodage ANSI mais est considérée comme ayant un encodage UTF-8.

    L'encodage par définition pour l'enregistrement sera déjà UTF-8 par défaut.

    C'est ce que j'ai tenté de faire. En raisonnant, je me suis vite rendu à la conclusion que VS pouvait difficilement deviner de lui-même l'encodage qu'il devait utiliser.

    J'ai donc tenté de faire cela mais dans System.Text.Encoding, je ne trouve pas ANSI. Je trouve ASCII, Unicode et les différents UTF. Quid pour ANSI ?

  6. #6
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Pour du ANSI Western European, utilise : Encoding.GetEncoding(1252);

  7. #7
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Pour du ANSI Western European, utilise : Encoding.GetEncoding(1252);
    Fallait le savoir ça !

    Je vais tester cela tout de suite.

  8. #8
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par griftou Voir le message
    Fallait le savoir ça !

    Je vais tester cela tout de suite.
    L'ANSI est une extension à 8 bits de l'ASCII, qui est à l'origine un code sur 7 bits. Or, il y a plusieurs interprétation possible du 8ème bits, donc plusieurs ANSI. Le 1252 correspond à l'ANSI "Western Europe" utilisé pour Windows.

  9. #9
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Pour compléter ce que Bluedeep vient de dire :

    * ASCII... 128 caractères, aucun accent. C'est un standard américain, pour américains.
    * ANSI... 256 caractères. Les valeurs 0 à 127 codent les mêmes caractères qu'en ASCII et on ajoute 128 caractères de plus. Les 128 caractères additionnels dépendent d'une page de code. ANSI Western European utilise ces emplacements pour des caractères accentués, ANSI Cyrillic pour des caractères cyrilliques, etc.
    * Unicode... Norme pour jusqu'à un demi-milliard de caractères (2^29 mais seulement 2^21 normalisés à ce jour). Les valeurs 0 à 127 codent les mêmes caractères qu'en ASCII. Plusieurs encodages possibles:
    *** UTF-8 : 1 à 4 octets par caractères (si le 8ème bit est vrai, on ajoute un second octet, si le 16ème bit est vrai on ajoute un troisième octet, etc.)
    *** UTF-16 : 2 ou 4 octets par caractère. Défaut pour Windows depuis NT et les chaînes du dotnet framework.
    *** UTF-32 : 4 octets par caractère.

    Pour unicode, l'identité d'un caractère (on parle de point de code) ne dépend pas de l'encodage : la point de code 512 donne le même caractère dans les trois encodages mais, en UTF-32 et UTF-16 il sera encodé comme sera 0x100 (9ème bit, 512) quand, en UTF-8, ce sera 0x200 (10ème bit, à cause du 8ème bit intercalaire signifiant qu'un second octet est nécessaire).

  10. #10
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Pour compléter ce que Bluedeep vient de dire :

    * ASCI... 128 caractères, aucun accent. C'est un standard américain, pour américains.
    Comme son nom (American Standard Code for Information Interchange ) l'indique. C'est une évolution du code Baudot 5 bits (bien de chez nous ) datant de .... 1874.

    Au demeurant, il y a eu aussi un ASCII 8 Bits, dit "ASCII paralléle" : il me semble que c'était le jeu de caractère utilisé par DOS (pas certain à 100%)

  11. #11
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Merci les gars ! Ca marche nickel avec l'ANSI Western European.

    J'en déduis donc qu'il est important de toujours spécifier l'encodage à utiliser lorsqu'on lit un fichier. Chose que je ne faisais absolument jamais jusqu'à présent

    Cela m'évoque une question corolaire...

    Y a-t-il un moyen de détecter l'encodage à utiliser ?

    Imaginons un hypothétique cas où il faudrait traiter des fichiers déposés sur un serveur ftp par des utilisateurs différents. Il est alors tout à fait possible que l'encodage de ces fichiers varient de l'un à l'autre.

    Comment faire pour les traiter correctement à ce moment-là ?

  12. #12
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    C'est possible en utilisant un dictionnaire : par exemple, mettons que "André" soit encodé en ANSI 1252 comme 65-72-54-45-145, si tu rencontres cette séquence dans un fichier texte tu donnes un point à l'encodage ANSI. Si la même séquence correspond aussi à un mot russe encodé en ANSI cyrillique, tu donnes un point également à cet encodage. A la fin, le gagnant l'emporte. On doit aussi pouvoir simplement se contenter de la fréquence d'occurence des divers caractères. A bien y réfléchir, c'est sans doute cette dernière méthode qui est vraiment utilisée : plus simple, plus rapide, capable de tirer parti des noms propres et des fautes d'orthographe.

    Pour l'anecdote, Visual studio identifie automatiquement l'encodage des fichiers sources et réencode sa copie en mémoire en Utf-16, ce qui fait que l'on n'a jamais besoin de se prendre la tête grâce à ça : nos commentaires sont toujours lus impeccablement quel que soit l'encodage utilisé.

    Mais, pour le FTP, j'ai un vague doute: je sais que les fichiers textes sont convoyés d'une façon spéciale mais j'imagine qu'il n'y a pas conversion de l'encodage au passage et que le contenu binaire sur le FTP reste le même que celui du fichier original. Mais bon, j'avais juste un doute, si quelqu'un peut confirmer ou infirmer...

Discussions similaires

  1. Insérer une ligne dans un fichier texte sans modifier l'encodage
    Par Benzeghiba dans le forum Framework .NET
    Réponses: 6
    Dernier message: 26/01/2009, 22h34
  2. [MySQL] Encodage des caractères dans un fichier texte
    Par louveteau02 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 04/04/2007, 10h41
  3. Type d'encodage de fichiers texte
    Par bit_o dans le forum GTK+ avec C & C++
    Réponses: 6
    Dernier message: 28/02/2007, 10h28
  4. Déterminer l'encodage du fichier texte
    Par ze.Ninus dans le forum Langage
    Réponses: 1
    Dernier message: 10/10/2006, 16h43
  5. [encodage fichier texte]
    Par nyko_kliko dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 28/07/2006, 16h21

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