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

  1. #1
    Membre du Club
    Homme Profil pro
    Aucune
    Inscrit en
    juillet 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Aucune

    Informations forums :
    Inscription : juillet 2019
    Messages : 49
    Points : 41
    Points
    41
    Par défaut Problème "Aucun mappage pour le caractère Unicode" lors de la lecture de certains fichiers avec TStreamReader
    Bonjour

    Mon code lit les fichiers csv sans problème exception faite d un. J ai un message d erreur Aucun mappage pour le caractère Unicode n'existe dans la page de code multi-octet cible

    Je suppose qu il s agit d un caractère qui pose problème mais lequel ?

    Y a t il un moyen de le retrouver s il s agit bien de cela ?

    Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    FileIn := TStreamReader.Create(ed_source.Text, true);
        while not FileIn.EndOfStream do
        begin
          inc(compteur);
          Memo1.Lines.Add(FileIn.ReadLine);
          if compteur > 2 then
            break;
        end;
        FileIn.Destroy;
    merci pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    7 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 534
    Points : 24 870
    Points
    24 870
    Par défaut
    cette erreur se produit par exemple quand tu cherches à décoder en UTF8 un texte ansi qui contient des caractères accentués.

    je n'ai jamais utilisé TStreamReader, en regardant le code cela semble devoir détecter le format du fichier...mais en fait uniquement sur le BOM (caractères d'entête)...sans BOM il prend la valeur par défaut qui n'est pas la même sous Windows (ANSI) et Android (UTF8) notamment - j'ai eu la blague.

    il faudrait ouvrir le csv sous NotePad++ et regarder dans le menu Encodage ce qu'il en dit.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    11 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2007
    Messages : 11 264
    Points : 29 185
    Points
    29 185
    Billets dans le blog
    29
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    je n'ai jamais utilisé TStreamReader
    Moi non plus
    Déjà il devrait être possible de jouer sur le Create pour forcer la détection voire l'encodage (ou plutôt le décodage)
    constructor Create(Stream: TStream); overload;
    constructor Create(Stream: TStream; DetectBOM: Boolean); overload;
    constructor Create(Stream: TStream; Encoding: TEncoding; DetectBOM: Boolean = False; BufferSize: Integer = 4096); overload;
    Mais puisqu'il s'agit de fichier CSV je me demande si un TextFile ou, s'il faut passer par un stream, TFileStream ne serait pas suffisant
    quoique il y ait d'autres méthodes (par exemple avec Firedac) pour traiter les fichiers CSV
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  4. #4
    Membre du Club
    Homme Profil pro
    Aucune
    Inscrit en
    juillet 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Aucune

    Informations forums :
    Inscription : juillet 2019
    Messages : 49
    Points : 41
    Points
    41
    Par défaut
    Merci pour vos réponses.

    J ai sauvegardé mon fichier sous UTF-8 with BOM et cela fonctionne.

    Concernant l'emploi du TStreamReader... Comme je débute j ai cherché des tutos sur la façon de lire de grands fichiers plus rapidement qu'avec le ReadLn.

    J ai effectivement trouvé le TFileStream mais étant donné que je débute, je suis allé au plus simple. Avec le TStreamReader je lis la ligne en une seule fois alors qu avec le TFileStream je lisais caractère par caractère et reconstituais la ligne quand je lisais le saut de ligne... Mais peut être je ne l utilisais pas comme il faut....
    .
    En écrivant ces lignes je le dis que le TFileStream serait plus approprié étant donné que j "explode" la ligne lue. Je n aurais qu'à repérer le caractère séparateur pour chaque parties et le saut de ligne à la fin....
    Je vais faire des tests...

  5. #5
    Membre du Club
    Homme Profil pro
    Aucune
    Inscrit en
    juillet 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Aucune

    Informations forums :
    Inscription : juillet 2019
    Messages : 49
    Points : 41
    Points
    41
    Par défaut
    Pour info voici les resultats de mes tests.
    Je lis un petit .csv de 511 lignes:

    Lu avec TStreamReader et "explode" de la ligne: 3 à 7 millisecondes.

    Lu avec TFileStream caractère / caractère: 85 ms.

    Lu avec TBufferedFileStream caractère / caractère: 1 ms. !!

    Je ne connais pas la taille des fichiers à lire mais certains peuvent être très gros. Mon idée est de déterminer la taille du fichier à lire et la comparer avec la taille de la mémoire disponible et selon le cas utiliser un TBufferedFileStream ou un TStreamReader.

    Donc ma question est la suivante : comment connaitre la mémoire disponible sur le système et surtout comment déterminer une "marge de manœuvre" suffisante pour ne pas avoir de dépassement mémoire car lire les données ok mails il y a leur traitement, l affichage ?

    Merci pour vos conseils

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    7 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 534
    Points : 24 870
    Points
    24 870
    Par défaut
    avec TFileStream tu n'es pas obligé de lire caractère par caractère, TBufferedFileStream utilise un buffer interne pour lire par bloc, c'est pour cela qu'il est plus rapide. Donc soit tu utilises cela, soit tu lis par bloc toi même.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre du Club
    Homme Profil pro
    Aucune
    Inscrit en
    juillet 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Aucune

    Informations forums :
    Inscription : juillet 2019
    Messages : 49
    Points : 41
    Points
    41
    Par défaut
    le pb que j ai avec le TFileStream c est que l on doit préciser la taille de ce que l on veut lire et moi elle n est pas fixe cette taille car le fichier n est pas organisé toujours de la même façon. Par exemple pour les dates c est un vrai pb pke certaines sont au format yyyy-mm-dd alors que d autres au format jj/mm/aaaa ou unix, tout dépend d'où j ai extrait les données....

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    7 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 7 534
    Points : 24 870
    Points
    24 870
    Par défaut
    Citation Envoyé par Debutant_pc Voir le message
    le pb que j ai avec le TFileStream c est que l on doit préciser la taille de ce que l on veut lire et moi elle n est pas fixe cette taille car le fichier n est pas organisé toujours de la même façon. Par exemple pour les dates c est un vrai pb pke certaines sont au format yyyy-mm-dd alors que d autres au format jj/mm/aaaa ou unix, tout dépend d'où j ai extrait les données....
    on ne s'est pas compris.

    la lecture d'un fichier disque est une opération lente...ce que TBufferedStream fait, c'est de lire la fichier par paquet de 4096 octets (je crois de tête), et du coup la lecture totale est plus rapide. Tu peux faire le test de lire en boucle un FileStream octet par octet ou par bloques de 4096, tu verras une énorme différence de performance. La lecture la plus rapide sera celle qui prend des buffer de la taille des secteurs disque, puisque pour lire 1 octet il faut lire tout le secteur et en extraire un octet...ce qui prend autant de temps que de lire tout le secteur d'un coup et de conserver tous les octets dans un buffer en mémoire.

    et donc ensuite, tu peux lire caractère par caractère dans le buffer de 4096 octets, le 4097ième octet sera simplement le premier du second paquet.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre du Club
    Homme Profil pro
    Aucune
    Inscrit en
    juillet 2019
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Aucune

    Informations forums :
    Inscription : juillet 2019
    Messages : 49
    Points : 41
    Points
    41
    Par défaut
    Merci

    Effectivement je n avais pas compris.

    J avais lu la doc pourtant mais j imaginais que cela fonctionnait comme un readln et que l on précisait la longueur de la ligne avec le nombre d octets et que du coup tout allait être décalé.

    Donc c est enfin clair.
    merci

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 10/03/2016, 14h20
  2. Réponses: 5
    Dernier message: 26/06/2006, 10h35
  3. Problèmes lors de la lecture d'un fichier
    Par samothtronicien dans le forum C++
    Réponses: 5
    Dernier message: 27/05/2006, 01h05
  4. Problème lors de la lecture d'un fichier avec Input...
    Par Kronoob dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 18/11/2005, 19h55

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