Dialoganwendung: größere Datei laden

Rettig

Grünschnabel
Hallo,
ich möchte in einer Dialoganwendung eine größere Textdatei ca 1MB laden und ausgeben.
Funktioniert auch soweit, ist aber sehr langsam.
m_cstrWert ist in diesem Beispiel eine Membervariable vom Typ CString welche zu einem CEdit - Control (mehrzeilig) gehört.
Codeschnipsel:
Code:
   CString cstrLine ="";	
   CFile file;
   file.Open("Datei.txt", CFile::modeRead);

   CArchive ar(&file, CArchive::load);
    
    if (!ar.IsStoring())
    {
        while(ar.ReadString(cstrLine))
        {
	    m_cstrWert += cstrLine;
            m_cstrWert += "\r\n";            
        }   

    }
    ar.Close();
    file.Close();
    UpdateData(false);
Ich nehme an, das die meiste Zeit dafür draufgeht für m_cstrWert immer neuen Speicher zu besorgen.
Wie könnte ich anders an die Sache drangehen?
 
Die meiste Zeit geht drauf, um das File Byte für Byte reinzuladen, weil ReadString immer bis zum Zeilenende liest.

Hol dir doch die Grösse von der Datei, zwinge den CString auf dieselbe Grösse und lade den kompletten Klotz auf einmal rein. Das wird garantiert schneller. Wird aber irgendwann an Grenzen stossen.

Du könntest ja trotzdem auf Speicherblöcke gehen, aber diese zum Beispiel auf 64k beschränken. Selbst das wird ReadString meilenweit abhängen.
 
Erst einmal danke für die Antwort.
Ich habe da noch ein paar Fragen.
Wie zwinge ich einen CString zu einer bestimmten Größe ?
Wie bekomme ich dann die Zeilenumbrüche hin?

Was meinst du damit:
Du könntest ja trotzdem auf Speicherblöcke gehen, aber diese zum Beispiel auf 64k beschränken. Selbst das wird ReadString meilenweit abhängen.

Danke im vorraus
 
>Wie zwinge ich einen CString zu einer bestimmten Größe ?

Mit GetBuffer oder GetBufferSetLength. Zusätzlich bekommst du da einen Pointer auf die Adresse des Datenblocks raus. Nach dem Einlesen ReleaseBuffer aufrufen, wichtig!

>Wie bekomme ich dann die Zeilenumbrüche hin?
Mit Replace kannst du die Zeilenumbrüche aus der Datei gegen "\r\n" austauschen. Das geht im Speicher ca. 50x schneller als wenn das beim Einlesen der Datei passiert.


>Was meinst du damit ...
Das war auf meinen Hinweis bezogen, dass man ja alles auf einmal einliest. Bei 1 MB mag das ja angehen, aber wenn du da plötzlich eine 64MB-Datei hast, ist das keine so gute Idee mehr. In dem Fall würde ich die Datei in 64kb-Blöcken einlesen, Zeilenumbrüche ersetzen und an den kompletten Text anhängen.


Direkt in einem Klotz würde in etwa so aussehen:

Code:
CString   cstrGnu;

// Speicher belegen
char*  pData = cstrGnu.GetBufferSetLength( file.GetLength() );

file.Read( pData, file.GetLength() );

// Speicher wieder umbelegen/freigeben
cstrGnu.ReleaseBuffer();

// Zeilenumbrüche ersetzen (Achtung, gibt mehrere Zeilenumbrucharten!, \xd und \xa entspricht ASCII 13,10)
cstrGnu.Replace( "\xd\xa", "\r\n" );

// jetzt sollte in cstrGnu der komplette Text fertig formatiert rumliegen
 
Zurück