Announcement

Collapse
No announcement yet.

Zeichenkette am Ende einer Datei entfernen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zeichenkette am Ende einer Datei entfernen

    Hallo,

    zurzeit stellt sich mir folgendes Problem: Ich habe eine Datei, an deren Ende ich springen muss, um (meistens) bestimmte acht Zeichen zu entfernen.

    Man kann sich die Datei vorstellen, wie ein XML-Dokument

    <begin>
    <tag>Inhalt</tag>
    </begin>

    Nun möchte ich zwischen die Zeile "<tag>Inhalt</tag>" und "</begin>" noch eine weitere anhängen, sodass es vielleicht entsprechend so aussieht:

    <begin>
    <tag>Inhalt</tag>
    <tag2>Inhalt2</tag2>
    </begin>

    Was ich nun mache ist folgendes:
    - Einlese der Datei in einen String (mOldContent)
    - mOldContent->remove(mOldContent->lastIndexOf("</begin>"), 8);
    - mOldContent->append(*mNewContent);
    - mOldContent->append("</begin>");

    Das funktioniert auch recht einfach, nur kann es sein, dass (JA! Kunde...) die Datei bis zu 50MB groß wird. Und wer weiß wie groß noch.... Das Einlesen in einen String würde in dem Szenario also zuviel Zeit brauchen - unsinnig Zeit, wie ich finde.

    Gibt es nun irgendeine Möglichkeit der "low level" Dateioperationen, wo der Inhalt nicht erst komplett in einen String geschrieben wird und ich später mittels String-Matching mir mein gewünschten Teilstring heraussuche und damit hantiere, sondern die Datei direkt durchsuche, und entsprechend manipuliere?

    Ich arbeite mit folgenden Utensillien: WinXP, Qt 3.11, Visual Studio 2008.

    Falls jemand Fragen oder Vorschläge hat, bitte her damit!




    LG Tom

  • #2
    Da du hier in der Datei etwas "mitten rein setzt" gibt es nur noch die Möglichkeit, die Datei zeilenweise zu lesen, prüfen ob etwas reinzusetzen ist, und jede Zeile in eine neue Datein rein zu schreiben.
    Christian

    Comment


    • #3
      Qt 3.11
      Aktuell wäre die Version 4.6, aber die Klasse QTextStream könnte hier weiterhelfen.
      MfG
      Cheat-Sheets for Developers / Programming Quotes

      Comment


      • #4
        Originally posted by Tom Dob View Post
        Ich arbeite mit folgenden Utensillien: ... , Visual Studio 2008.
        Und wieso postet man sowas beim C++-Builder?

        Comment


        • #5
          Verschoben, da ich nun nicht weiss, mit QT, VS -> in den allg. Teil

          Er weiss auch nicht, ob es um das Entfernen oder hinzufügen geht. Lt. Überschrift soll etwas entfernt werden. Lt. Text wird etwass hinzugefügt.

          Und am "Ende der Datei" ist auch sehr weiträumig
          Christian

          Comment


          • #6
            Hallo,

            vielen Dank für die Beiträge.

            Und wieso postet man sowas beim C++-Builder?
            Tut mir leid, dass ich das Posting im falschen Thread erstellt habe. Vielen Dank auch für das Verschieben!

            Aktuell wäre die Version 4.6, aber die Klasse QTextStream könnte hier weiterhelfen.
            Ich weiß, nur wird hier leider noch 3.11 eingesetzt, wovon ich mich einfach nicht losreissen kann.

            Lösen habe ich es wiefolgt können:
            Code:
            	FILE *f;
            	f = fopen(mFileName.toAscii(), "r+");
            	if (f != NULL)
                {
                    fseek(f, 0, SEEK_END);
            		int size = ftell(f);
            
            		if (size < 9)
            			return;
            
            		fseek(f, size-9, SEEK_SET);
            		fwrite(mNewContent->toAscii(), mNewContent->size(), 1, f);
            		const char end_tag[] = "</begin>";
            		fwrite(end_tag, sizeof(char)*strlen(end_tag), 1, f);
            		fclose(f);
                }
            Wobei das Qt und C gemischt ist. Es gibt etwaige äquivalente Funktionalitäten aber auch auf Qt-Ebene. Diesen Code hier zu posten fände ich aber falsch angesiedelt, darum auch der Preudecode zur Veranschaulichung.

            mFileName ist eine Qt-Variable vom Typ QString, welche eine Funktion toAscii() hat, die ein Array auf char zurückgibt.

            Nur gehe ich jetzt in meinem Beispiel davon aus, dass am Ende der Datei (also die letzten sichtbaren Zeichen, die in der Datei stehen) eine Zeile "</begin>" steht, welche 8(+1) Zeichen lang ist.

            Gut, damit muss ich leben, dafür muss ich nicht den kompletten Inhalt der Datei (zeilenweise) auslesen, in einem Objekt (einem String) speichern, um dann dort Matching-Operationen auszuführen (find/indexOf), um danach noch weiteren Inhalt dem Objekt hinzuzufügen, um dann das abgeänderte Objekt wieder in einer Datei zu speichern.

            Nun "quetsche" ich den Inhalt (mNewContent) einfach vor den Ausdruck "</begin>". Würde dort "</begin >" stehen, also mit Leerzeichen, so würde der Text, den ich neu hinzufüge, natürlich auch zwischen das "b" und das "e" von begin geschrieben. Weniger gut, doch extrem perfomant.

            Leider habe ich keinerlei Such-Funktionen auf Datei-Ebene gefunden, weshalb ich die exakte Position des (in dem Falle) schließenden Tags nicht herausfinden kann. Darum die dirty Version, dass ich davon ausgehe, dass am Ende wirklich die gewünschten 9 Zeichen stehen (\n, also 0A + den Text mit 8 Zeichen Länge).

            Falls ich etwas übersehen habe, oder eine Suchfunktion für Dateien doch existiert, dann lasset es mich bitte wissen.



            LG Tom

            Comment


            • #7
              Leider habe ich keinerlei Such-Funktionen auf Datei-Ebene gefunden
              Wie auch. Das ersetzen in einer Datei wäre nur möglich, wenn

              - exakt die gleiche Länge ausgetauscht werden soll oder
              - etwas am Ende gekürzt oder überschrieben werden soll

              Beides trifft hier nicht zu.

              Deine Lösung erscheint bei Dateien die eine unbekannte Größe haben können, nicht zielführend. Siehe Beitrag 2
              Christian

              Comment


              • #8
                Hallo Christian,

                etwas am Ende gekürzt oder überschrieben werden soll
                Ich habe eine Datei, an deren Ende ich springen muss, um (meistens) bestimmte acht Zeichen zu entfernen.
                Dieses "meistens" kann durch die nun eingesetzte Methode getroßt ignoriert werden, da ich somit definiere, dass diese acht Zeichen am Ende stehen MÜSSEN! Ich beschreibe die Datei maschinell, und --eigentlich-- sollten die letzten acht Zeichen exakt diese sein, die ich auch erwarte.

                Dies kann NUR manipuliert werden, wenn manuell eingegriffen wird. Darauf werde ich aber durch einen kleinen Schrieb und ein böses "Wehe, Wehe" bestehen müssen, dass dies nicht geschieht, ansonsten kann nicht für eine konsistente Datei garantiert werden.

                Ich gehe nun also davon aus, dass die Dateien eher so riesig werden, alsdass ein Kunde manuell eingreift, weshalb ich auch die schnellere (/unsicherere Variante) gewählt habe.

                Ich suche nun eine Art "truncate" oher "resize" auf Datei-Ebene, aber da bin ich sicher, fündig zu werden. Daran hatte ich garnicht gedacht, dass ich ja auch einfach die Datei um 8 Zeichen kürzen kann, um später den neuen Inhalt per "append" hinzuzufügen.

                Nur glaube ich nicht, dass der Unterschied zwischen "hereinquetschen" und "appenden" soo riesig sein wird, dass wirklich signifikante Unterschiede zu spüren sind oder sehe ich das falsch?



                LG Tom

                Comment


                • #9
                  Hier ist beispielsweise das Suchen in Dateien realisiert:

                  http://www.marquardtnet.info/cecke/p...4_wingrep.html

                  Wenn es wirklich am Ende ist, ist das überschreiben oder kürzen die beste Methode

                  Ja, ein truncate gibt es. Je nachdem ob du die Standard C/C++ Funktionen, Streams oder MS Funktionen nutzt
                  Christian

                  Comment

                  Working...
                  X