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

Téléchargez Pascal Discussion :

File Encoding Expert [Sources]


Sujet :

Téléchargez Pascal

  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut File Encoding Expert
    Bonjour,

    Je vous propose un nouvel élément à utiliser : File Encoding Expert

    File Encoding Expert est une application réalisée avec Lazarus, qui utilise trois façons différentes de détecter l'encodage d'un fichier, permettant ainsi de comparer les résultats obtenus, qui ne sont pas toujours concordants !

    Nom : utf8.png
Affichages : 478
Taille : 17,0 Ko

    L'application est bâtie, d'une part, sur la fonction GuessEncoding() de l'unité LConvEncoding de Lazarus ; d'autre part sur une fonction équivalente de Delphi (XE2), préalablement exportée dans une bibliothèque dynamique ; enfin sur la bibliothèque Charset Detector :

    http://chsdet.sourceforge.net/

    Qu'en pensez-vous ?

  2. #2
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Testé : OK mais à la condition que le chemin des fichiers testés ne comportent QUE des caractères 'US-ASCII' (< #128). Echec sinon .

    Quant au fait que les résultats puissent être différents, ce peut être normal. Un fichier donné, selon son contenu, peut correspondre à plusieurs pages de code possibles et la fonction, ne renvoyant qu'un seul résultat, doit choisir.

    La plupart des fonctions se contentent de rechercher certaines métadonnées au début du fichier et en leur absence, se replient sur une valeur par défaut. Par exemple pour un fichier pur 'US-ASCII' LConvEncoding privilégie UTF8, alors que la quasi-totalité des pages de code fondées sur l'ASCII soient aussi possibles. D'autres fonctions privilégieront la page de code par défaut définie par le système en fonction de sa localisation.

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par DomDA91 Voir le message
    Testé : OK mais à la condition que le chemin des fichiers testés ne comportent QUE des caractères 'US-ASCII' (< #128). Echec sinon .
    Merci pour l'essai et pour m'avoir signalé cette erreur. Il faudra que je m'y penche. Là tout de suite je n'ai pas en tête les modifications à faire.

    Citation Envoyé par DomDA91 Voir le message
    Quant au fait que les résultats puissent être différents, ce peut être normal. Un fichier donné, selon son contenu, peut correspondre à plusieurs pages de code possibles et la fonction, ne renvoyant qu'un seul résultat, doit choisir.

    La plupart des fonctions se contentent de rechercher certaines métadonnées au début du fichier et en leur absence, se replient sur une valeur par défaut. Par exemple pour un fichier pur 'US-ASCII' LConvEncoding privilégie UTF8, alors que la quasi-totalité des pages de code fondées sur l'ASCII soient aussi possibles. D'autres fonctions privilégieront la page de code par défaut définie par le système en fonction de sa localisation.
    Excellent résumé, me semble-t-il. Merci !

    Sur les trois fonctions que le programme utilise, la seule qui ne se contente pas, justement, des métadonnées (et même qui les ignore, si je ne me trompe), c'est la fonction de la bibliothèque Charset Detector. Je n'ai pas regardé le code source, mais j'ai cru comprendre que la fonction cherche à reconnaître les lettres caractéristiques d'une langue et ensuite en déduit la page de code appropriée. Ce qui fait que si on lui donne un fichier ne contenant que des caractères ASCII, elle renvoie 0.

  4. #4
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    ... Là tout de suite je n'ai pas en tête les modifications à faire.
    Moi j'ai un peu regardé. La solution sera d'ailleurs différente selon que l'on compile sous Lazarus 1.4/FPC 2 ou pour le nouveau Lazarus 1.6/FPC 3.0.

    Avec Lazarus 1.4, il suffit de saupoudrer 7 ou 8 "UTF8ToSys" (ou "SysToUTF8"), chaque fois que l'on passe une spécification de fichier à une fonction de la RTL qui elle ne connaît que l'Ansi.

    Avec Lazarus 1.6, ce n'est, en principe, plus nécessaire car les conversions se font automatiquement. J'ai essayé : ça marche pour "LconvEncoding" et pour "chsdet.dll" mais la fonction "encoding.dll" elle renvoie toujours 0.
    Je pense qu'ici le problème vient de ce que le paramètre est passé à la DLL via un pChar et que dans ce cas il n'y a pas de conversion automatique. Il faut donc forcer explicitement la conversion.
    Sur mon PC (Windows 8.1/Configuré France) un forçage, en dur, à CP1252 fonctionne, mais il faudrait pouvoir connaître exactement, par programme, la page de code qu'utilise la machine cible.
    Je cherche à cet effet une fonction de la RTL qui fasse cette conversion ou qui, au moins, retournerait la page de code à utiliser. Je pense avoir une piste et je confirmerait après vérification.

    Citation Envoyé par Roland Chastain Voir le message
    Sur les trois fonctions que le programme utilise, la seule qui ne se contente pas, justement, des métadonnées (et même qui les ignore, si je ne me trompe), c'est la fonction de la bibliothèque Charset Detector. Je n'ai pas regardé le code source, mais j'ai cru comprendre que la fonction cherche à reconnaître les lettres caractéristiques d'une langue et ensuite en déduit la page de code appropriée. Ce qui fait que si on lui donne un fichier ne contenant que des caractères ASCII, elle renvoie 0.
    En fait elle reconnaît tout de même le BOM qui, selon la définition générale qu'en donne Wikipedia, peut être considéré comme une forme particulière de métadonnée. Je n'ai pas non plus examiné le source de près mais le simple examen des noms de fichier et le volume global du projet (plus de 400Ko) est assez parlant. D'autant plus que reconnaître les lettres caractéristiques d'un langage, alors que l'on ne sait pas encore par quel code elles sont représentées, ne doit pas être très simple !

  5. #5
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Bon ! finalement la solution est plutot simple c'est Utf8ToWinCP.
    Ce qui l'est moins c'est cette f... documentation. Une page du Wiki Lazarus fait bien mention de cette fonction (et de son opposé WinCPToUtf8) mais ne précise pas l'unité qui la contient. Comme elle est mentionnée sous un gros titre "RTL ... etc." j'ai naïvement cru que cétait une nouvelle fonction de FPC 3.0. Après de nombreux essais soldés par un "Identifier not found" j'ai fini par abandonner pour rechercher autre chose. C'est au cours de ces recherches que je suis tombé dessus par hazard, dans l'unité LazUtf8 de la LCL. Les fonctions Utf8ToWinCP et WinCPToUtf8 sont nouvelles et ne figurent pas (encore ??) dans aucun des CHM installés avec la 1.6RC2.

    Pour l'appel de GetEncoding il suffit donc d'ajouter LazUtf8 dans le Uses et de coder :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       result := GetFileEncoding(PAnsiChar(Utf8ToWinCP(Edit1.Text)));
    Remarque : Comme la fontion Utf8ToWinCp est nouvelle il faudra peut-être prévoir des directives de compilation conditionelle pour s'adapter aux versions nouvelle et anciennes de Lazarus.

    Autre suggestion :
    Ce serait bien d'effacer le contenu d'Edit3 lorsque le résultat de la fonction est 0. En effet, dans ce cas, le libellé de l'analyse précédente reste affiché et cela peut induire l'utilisateur en erreur. Pareil pour Edit5.

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par DomDA91 Voir le message
    Bon ! finalement la solution est plutot simple c'est Utf8ToWinCP.
    ...

    Pour l'appel de GetEncoding il suffit donc d'ajouter LazUtf8 dans le Uses et de coder :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       result := GetFileEncoding(PAnsiChar(Utf8ToWinCP(Edit1.Text)));
    Remarque : Comme la fontion Utf8ToWinCp est nouvelle il faudra peut-être prévoir des directives de compilation conditionelle pour s'adapter aux versions nouvelle et anciennes de Lazarus.
    Merci pour cette suggestion et pour vos recherches.

    Auparavant j'avais essayé (conformément à votre suggestion précédente) ceci, qui m'a paru fonctionner correctement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      //if not FileExists(Edit1.Text) then
      if not FileExists(UTF8ToSys(Edit1.Text)) then
      ...
     
      //s := LoadStringFromFile(Edit1.Text);
      s := LoadStringFromFile(UTF8ToSys(Edit1.Text));
      ...
     
      //result := GetFileEncoding(PAnsiChar(Edit1.Text));
      result := GetFileEncoding(PAnsiChar(UTF8ToSys(Edit1.Text)));
    Mais je prends note quand même de l'existence de cette fonction UTF8ToWinCP.

    Citation Envoyé par DomDA91 Voir le message
    Autre suggestion :
    Ce serait bien d'effacer le contenu d'Edit3 lorsque le résultat de la fonction est 0. En effet, dans ce cas, le libellé de l'analyse précédente reste affiché et cela peut induire l'utilisateur en erreur. Pareil pour Edit5.
    Bien vu. Je vais faire la correction.

  7. #7
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    Citation Envoyé par DomDA91 Voir le message
    [...]
    Remarque : Comme la fontion Utf8ToWinCp est nouvelle il faudra peut-être prévoir des directives de compilation conditionelle pour s'adapter aux versions nouvelle et anciennes de Lazarus.
    [...]
    En fait, et bien que je ne sache avec précision depuis quand ces 2 fonctions existent, ce qui est certain c'est qu'elles existent depuis déjà quelques temps (probablement depuis la version 1.4.0).

  8. #8
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Citation Envoyé par FChrisF
    En fait, et bien que je ne sache avec précision depuis quand ces 2 fonctions existent, ce qui est certain c'est qu'elles existent depuis déjà quelques temps (probablement depuis la version 1.4.0).
    Ah merci, j'ignorais. Effectivement les fonctions Utf8ToWinCP et WinCPToUtf8 sont là, bien cachées dans LazUtf8 de mon Lazarus 1.4.2.

    Sous Lazarus 1.4 elles ont une fonction semblable à, respectivement, Utf8ToSys et SysToUtf8.

    Avec Lazarus 1.6 leur comportement diffère :
    • UTF8ToSys et SysToUtf8 sont maintenant des fonctions "zombies", qui se contentent de renvoyer leur paramètre sans changement, laissant jouer la conversion automatique s'il y a lieu.
    • Utf8ToWinCP et WinCPToUtf8 font explicitement la conversion qui convient en tenant compte de l'encodage de la chaîne passée en paramètre et l'encodage ANSI par défaut du système.



    @Roland Chastain :

    Compte-tenu de ce qui précède, on pourrait dès maintenant coder le projet comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Uses LazUtf8, ...
     
     
    //  if not FileExists(Edit1.Text) then
        if not FileExists(UTF8ToSys(Edit1.Text)) then
     
    //  s := LoadStringFromFile(Edit1.Text);
        s := LoadStringFromFile(UTF8ToSys(Edit1.Text));
     
    //result := GetFileEncoding(PAnsiChar(Edit1.Text));
             { Attention, ici Utf8ToSys ne marcherait pas en 1.6 }
      result := GetFileEncoding(PAnsiChar(UTF8ToWinCP(Edit1.Text)));

    Par ailleurs dans FormCreate les paramètres, récupérés de la ligne de commande, sont en Ansi et doivent aussi être convertis en Utf8 s'ils sont passés à une routine LCL :

    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
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      if ParamCount = 0 then
    //  ListBox1.Items := FindAllFiles(ExtractFilePath(ParamStr(0)) + 'samples', '*.*', FALSE)
        ListBox1.Items := FindAllFiles(SysToUTF8(ExtractFilePath(ParamStr(0))) + 'samples', '*.*', FALSE)
      else
        if DirectoryExists(ParamStr(1)) then
    //    ListBox1.Items := FindAllFiles(ParamStr(1), '*.*', FALSE)
          ListBox1.Items := FindAllFiles(SysToUtf8(ParamStr(1)), '*.*', FALSE)
        else
          if FileExists(ParamStr(1)) then
    //      Edit1.Text := ParamStr(1);
            Edit1.Text := SysToUtf8(ParamStr(1));
    end;
    Ainsi modifié, le projet devrait pouvoir être compilé et fonctionner aussi bien avec la version 1.6 qu'avec les versions 1.4 précédentes, sans nécessiter aucun changement.

    À signaler aussi les nouveautés de l'unité SysUtils de la RTL livrée avec Lazarus 1.6 :
    • Classe TEncoding qui permet de ré-écrire en Free Pascal un équivalent de ce que fait la DLL Encoding de Delphi (une quatrième façon à ajouter à FileEncodingExpert ?) ;
    • Routines de conversion CodePageToCodePageName et CodePageNameToCodePage. Va-t-on vers une uniformisation des libellés ? Ce ne serait pas dommage car entre les directives $CODEPAGE de FPC, les noms de constantes TSystemCodePage (unité System), la macro Lazarus %encoding (reconnue par LazUtils.GuessEncoding), les noms de fichier source de la RTL (CPxxx.pas) et j'en passe, c'est actuellement une belle cacophonie !

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par DomDA91 Voir le message
    Compte-tenu de ce qui précède, on pourrait dès maintenant coder le projet comme suit :
    Merci bien pour toutes ces corrections. Je les ai faites et j'ai mis à jour le téléchargement.

  10. #10
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut
    J'ai passé un coup de chiffon dans ce projet. Je voulais voir s'il fonctionnait sous Linux. J'ai retiré la bibliothèque faite avec Delphi.

    Vous trouverez sur la page de téléchargement la nouvelle version du projet, incluant les sources de la bibliothèque ChsDet et un script pour la compiler.

    Nom : fileencodingexpert-cropped.png
Affichages : 347
Taille : 43,8 Ko

    Je ne sais pas pourquoi les noms de fichiers dans la TListBox sont autant espacés. Bon, peu importe...

  11. #11
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 089
    Points : 15 518
    Points
    15 518
    Billets dans le blog
    9
    Par défaut
    Bonjour ! J'ai retravaillé ce projet. J'ai ajouté deux commandes supplémentaires : file et uchardet. Je n'ai pas inclus les binaires Windows. C'est à l'utilisateur de se les procurer et soit de modifier le chemin des exécutables dans les fichiers file.cmd et uchardet.cmd, soit d'appeler directement les exécutables depuis l'application (au lieu d'exécuter les fichiers *.cmd). Mais même en l'état actuel l'application devrait fonctionner et gérer l'erreur en douceur : il y aura simplement un message disant que les exécutables sont introuvables.

    Voilà. Vos retours éventuels sont bienvenus.

    Nom : encodex-cropped.png
Affichages : 313
Taille : 27,1 Ko

    File Encoding Expert 2022

Discussions similaires

  1. Encoding - Read a file without =E9 =2C, etc
    Par gitch dans le forum C#
    Réponses: 0
    Dernier message: 14/07/2010, 12h59
  2. encoding file par défaut
    Par Papy214 dans le forum NetBeans
    Réponses: 2
    Dernier message: 23/09/2009, 16h21
  3. Réponses: 5
    Dernier message: 04/06/2009, 10h47
  4. Réponses: 1
    Dernier message: 26/02/2009, 16h32
  5. applet signe et file encoding ?
    Par pcouas dans le forum Applets
    Réponses: 1
    Dernier message: 21/01/2009, 09h39

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