Wie handhabt man laaange Strings



  • Hallo,

    um das Problem grob zu umreissen folgende Erklärung. Bei mir fallen täglich bei der Arbeit Dateien an, die ich wie folgt bearbeiten muss: Öffnen der Datei, Austauschen zweier Begriffe, Schließen der Datei.
    Für kleiner Dateien habe ich mir bereits ein fertiges Programm geschrieben. Übersteigen die Dateien jedoch bspw. 2 Mio. Zeichen, so bekomme ich nur noch fehler. Sämtliche CString-Routinen (bspw. GetLength (...)) arbeiten mit int-Werten, so dass mir die Ursache schon relativ klar ist.
    Wie sollte man also mit so großen Strings (bis bspw. 5MByte) arbeiten?

    Gruß, Andy



  • wenn die grösse überschaubar bleibt kannst du ja mehrere strings aneinanderreihen.

    Esco



  • Hatte ich mir auch schon überlegt, aber es wäre halt schön, wenn es eine elegantere Methode gäbe. Allerdings funktioniert so die .Write (String, unint Länge) - Routine nicht mehr, da ich einen String länger als ein unsigned int schreiben möchte.



  • mit einem 32-bit unsigned integer kann man schonmal 2 GB dateien verwalten.
    das wird ja wohl reichen.



  • Theoretisch schon 🙂

    Die Fehlerursache scheint bei mir schon in der Deklaration des Array während der Laufzeit zu liegen (auf Knopfdruck):

    0xc00000fd

    Thread Stack Size Checking
    Stacks
    The stacks test ensures that an application has sufficient stack space as this test disables stack growth after the test starts. If an application does not have sufficient stack space, the application crashes with 0xC00000FD, (STATUS_STACK_OVERFLOW), and an Application Verifier stop message does not display. This check is critical for services and other system processes which run after the operating system has booted - examples include winlogon, csrss, smss, and services in general.

    Hat vielleicht jemand eine Idee, wie dieser Fehler zu umgehen ist. Sollte ich dieses Array schon in meiner Klassendefinition initialisieren?



  • Den Speicher dynamisch auf dem Heap allozieren. Da kommst du gut bis ein paarhundert meg, kommt dann halt auf den Rechner und deine Anwendung an.

    Laden-ersetzen-Speichern ist die einfachste und portabelste Methode, wenn du Dateigrößen unter 100MB erwartest und deine Anwendung sonst nicht viel macht, würde ich erstmal dabei bleiben 8es sei denn, es ist zu langsam).

    Unter Windows bieten sich für größere Dateien Memory Mapped Files an - ist bei deiner Anwendung aber nur sinnvoll, wenn der Ersatzstring die gleiche Länge hat wie der originale. Evtl. noch wnn er kürzer ist, aber wenn du praktisch zeichen Einfügen mußt, ist sequentiell lesen und umkopierne wohl am effektivsten.



  • Ich frage mich warum du die ganze Datei in eine String lädst.
    Wenn es Textdateien sind lade sie Zeile für Zeile. Wenn du keine Zeilenendezeichen hast dann immer nur eine bestimmte Anzahl Zeichen.

    Wenn du eine Klasse auf dem Stack erstellst und nichts in VC++ sonst einstellst dann hast du dort 1 MB zur verfügung. Das kann schnell zu klein werden.



  • @Unix-Tom

    Danke, du hast mir den entscheidenden Hinweis gegeben. Man kann die Stacksize in den Linkeroptionen des Programms einstellen, so dass nun auch größere Arrays kein Problem mehr darstellen. Dies geht allerdings mit einem höheren Arbeitsspeicherbedarf einher, womit ich allerdings leben kann.

    Danke nochmal für eure Mühe,
    Andy



  • Du sollst ja den Stack nicht erhöhen.
    Dafür gibt es den Heap



  • Nur das ein Rücksetzen der Stackparameter auf 0 (Standard) und eine Variation der Werte für den Heap weiterhin zu einem Stack-Overflow meiner Anwendung führt. Wenn ich den Stack vergrößere, funktioniert es ohne Probleme.

    Wo ist mein Denkfehler?



  • Dein Denkfehler ist das du ein so großes File nicht in eine Rutsch einlesen musst.



  • Warum liest du die Datei nicht Block, oder Zeilenweise aus wie es hier schon geschrieben wurde.

    zB so:
    [PseudoCODE]

    OutDatei öffnen
    NeueDatei öffnen
    
    while(OutDatei.lese(str))
    {
     rplacestring(str,"bla");
     NewDatei.Write(str);
    }
    
    OutDatei schliesen
    NeueDatei schliesen
    
    Delete OutDatei
    Rename NewDatei-> OutDatei
    

    [/PseudoCODE]

    Mfg Col.Blake


Anmelden zum Antworten