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

C++Builder Discussion :

Out of memory avec un TStringList [IDE]


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut Out of memory avec un TStringList
    Bonjour,

    J'utilise un TSringList, mais si le fichier à générer est trop gros j'ai un Out Of Memory au moment du SaveToFile
    Voilà un bout de code pour tester le problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	TStringList* list = new TStringList();
    	for (unsigned int i = 0; i < 200000 ; i++)
    	{
    		list->Add(StringOfChar('p', 1500));
    	}
    	list->SaveToFile("toto", TEncoding::UTF8); // out of memory
    	delete list;
    Il me parait évident qu'il va falloir que je trouve autre chose pour créer mon fichier
    N'étant pas très à l'aise avec les encodages et ayant besoin d'un encodage UTF8, que puis je utiliser comme autre solution qui supporte un encodage UTF8?
    C'est peut être trivial mais là je bloque...

    merci beaucoup pour votre aide
    Pascale38

  2. #2
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    c'est parfaitement normal tu est plus grand que la capacité mémoire par ailleurs ton code ne te génère pas un fichier au format UTF 8
    une des manières d'y parvenir est d'écrire ton fichier pas à pas

    dans ce code le fichier est 10 fois plus Gand que celui que tu aurais voulu obtenir soit 2.79*Go (3*000*000*003 octets)
    le temps nécessaire sur ma vieille bécane est de 30 secondes

    voici le code que je propose

    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
     
    { 
             TEncoding *LEncoding = NULL;
    	 int LOffset;
    	 UnicodeString Tmp("");
    	 TBytes myBytes;
    	 TDateTime StartTime, StopTime;
    	 StartTime = Now();
    	 std::auto_ptr<TFileStream>DestFileStream(new TFileStream("SampleUTF8.txt", fmCreate));
    	 std::auto_ptr<TBytesStream>myBytesStream(new TBytesStream(myBytes));
    	 TBytes LByteOrderMark;
    	 LByteOrderMark = TEncoding::UTF8->GetPreamble();
    	 DestFileStream->Write(&LByteOrderMark[0], LByteOrderMark.Length);
    	 for (int i(0); i < 2000000; i++) {
    		 Tmp += Tmp.StringOfChar('p', 1500);
    		 myBytesStream.get()->Write(Tmp.data(), Tmp.Length());
    		 LOffset = TEncoding::GetBufferEncoding(myBytes, LEncoding);
    		 myBytes = TEncoding::Convert(LEncoding, TEncoding::UTF8, myBytesStream->Bytes, LOffset,
    			 myBytesStream->Size - LOffset);
    		 DestFileStream->Write(&myBytes[0], myBytes.Length);
    		 Tmp = "";
    		 myBytesStream.get()->Position = 0;
    		 myBytes = 0;
    	 }
    	 StopTime = Now();
     
    	 ShowMessage(L"Creation en :" + FormatDateTime(L"nn:ss:zzzz", StopTime - StartTime));
     
     }
    bonne lecture
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    Bonjour,
    merci beaucoup !! Je m'en vais de ce pas tester ça !
    J'ai une question: pourquoi dis tu que mon fichier n'est pas en UTF8?

    Pascale38

  4. #4
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut,
    Le fait d’appeler Tencoding:: Uxxx ne génère pas de transformation , il faut appeler la méthode convert.
    Par ailleurs il manque dans ce cas la signature du fichier ou Preamble, différente pour chaque codage.
    Pour t’en convaincre réduit la génération du nombre de fichier par exemple 20 et ouvre le fichier dans un notepad.tu verras qu’il n’indique pas UTF8. Fais de même avec le code que j’ai proposé et tu verra la différence.
    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    merci pour ta réponse.

    alors j'ai 2 soucis :
    ne compile pas

    et il me rajoute un '\0' entre chaque caractère....

  6. #6
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    l'erreur de ne compille pas provient du compilateur en effet avec le compilateur BCC 32 il y a une erreur alors qu'avec le compilateur Clang ily n'y a pas d'erreur
    concernant le fichier généré
    un string of char de retourne un AnsiString dans ton cas "ppppppppppppppppppppppppppppp"
    pour le retour chariot il manque simplement dans mon code

    je te propose l'amélioration suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    AnsiString Tmp("");
    Tmp += Tmp.StringOfChar('p', 1500)+AnsiString("\r\n");
    et 
    effacer la mise é 0 du Mbyte
    cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  7. #7
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Pour revenir sur le codage UTF8 comme son suffixe indique c’est du 8 bits donc char ou unsigned char.
    Le type à utiliser est donc du AnsiString

    Concernant le type Tbyte. pour reseter la bariable Sous bcc32 il faut appeler la méthode setlength en mettant le paramètre à 0. Sous Clang il semblerait que ce soit implicite.

    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    Pourtant en utilisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list->SaveToFile("toto", TEncoding::UTF8);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list->SaveToFile("toto");
    j'obtiens bien des fichiers différents (notamment au niveau du traitement des '&').
    Et quand j'ouvre mon fichier (encodé avec UTF-8) avec notepad++ il me donne bien UTF-8-BOM comme encodage.

    Bon j'avoue ne pas maitriser du tout les encodages...

    En tout cas ça à l'air de fonctionner avec ton code merci, j'obtiens un encodage UTF-8-BOM UNIX par contre, bizarre???
    Mon ancien fichier lui est en encodage UTF-8-BOM PC
    (dixit beyond compare avec lequel je compare mes 2 fichiers)

  9. #9
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Mon explication est la suivante.
    La signature du fichier se trouve au début du fichier (les 3 premiers bytes) donc dans le traitement de la string list il y a lieu d’insérer au début du fichier la signature ce qui consomme de la mémoire.

    Il serait intéressant de comparer les signatures des deux fichiers générer par ton code avé c une boucle réduite et celui que j’ai posté
    Par contre lors je maintiens mes propos concernant la stringlist qui n’est pas adaptée au traitement de fichiers si grand


    je n'ai par contre pas pu reproduire la différence de BOM d' on tu parles

    Signature avec des String List et la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    list->SaveToFile("toto.txt", TEncoding::UTF8);
    BOM Ou Preamble ou signature oxef 0xbb 0xbf


    avec ma proposition de code
    BOM Ou Preamble ou signature oxef 0xbb 0xbf


    un rapide contrôle avec WinMerge me confirme que les fichiers sont en tout point identiqueNom : WinMergeCap.PNG
Affichages : 83
Taille : 45,7 Ko

    cordialement





    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    merci pour toutes tes explications
    Je confirme que TStringList n'est pas adapté !!!
    Je me pencherai plus sérieusement sur ces histoires d'encodage,
    en tout cas merci pour ton code qui m'a permis de trouver une solution alternative (en toute confiance surtout !!!)
    et de me débloquer

    Bonne soirée,
    Pascale38

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

Discussions similaires

  1. [Débutant] Out of memory avec réseau de neurones
    Par slaima15 dans le forum MATLAB
    Réponses: 6
    Dernier message: 25/06/2011, 20h29
  2. Out of memory avec memory_limit à -1
    Par steveleg dans le forum Langage
    Réponses: 3
    Dernier message: 22/09/2010, 16h45
  3. Out of memory avec plein de mémoire!
    Par JM-R dans le forum ASP.NET
    Réponses: 4
    Dernier message: 26/11/2007, 15h28
  4. Réponses: 15
    Dernier message: 11/05/2007, 16h55
  5. [DBDesigner] Out of memory avec DB Designer 4 et Mysql
    Par titeuf38 dans le forum DBDesigner
    Réponses: 5
    Dernier message: 03/05/2007, 13h00

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