2 Stimmen

Abschneiden der Datei in C++

Ich habe ein Programm in C++ geschrieben und frage mich, ob mir jemand mit der hier beschriebenen Situation helfen kann.

  1. Angenommen, ich habe eine Protokolldatei mit einer Größe von etwa 30 MB. Ich habe die letzten 2 MB der Datei in einen Puffer innerhalb des Programms kopiert.

  2. Ich lösche die Datei (oder lösche den Inhalt) und schreibe dann meine 2 MB zurück in die Datei.

Bis hierhin funktioniert alles einwandfrei. Aber das Problem ist, dass ich die Datei (die letzten 2MB) lese und die Datei (die 30MB Datei) lösche und dann die letzten 2MB zurückschreibe. Zu viel Zeit benötigt werden, wenn in einem Szenario, wo ich bin Kopieren letzten 300MB der Datei aus einer 1GB-Datei.

Hat jemand eine Idee, wie man diesen Prozess vereinfachen kann?

Bei einer großen Protokolldatei sollten und werden die folgenden Gründe berücksichtigt werden.

Speicherplatz: Protokolldateien sind unkomprimierter reiner Text und verbrauchen viel Speicherplatz. Eine typische Komprimierung reduziert die Dateigröße um 10:1. Eine Datei kann jedoch nicht komprimiert werden komprimiert werden, wenn sie in Gebrauch (gesperrt) ist. Daher muss eine Protokolldatei, die nicht mehr verwendet wird, rotiert werden.

System-Ressourcen: Das regelmäßige Öffnen und Schließen einer Datei verbraucht viel Systemzeit. Ressourcen und würde die Leistung des Servers beeinträchtigen.

Größe der Datei: Kleine Dateien sind leichter zu sichern und wiederherzustellen, falls ein Fehler auftritt.

Ich möchte nur nicht die letzten spezifischen Zeilen kopieren, löschen und erneut in eine Datei schreiben. Nur ein einfacheres Verfahren.... :-)

EDIT: Es wird kein interner Prozess zur Unterstützung der Protokollrotation durchgeführt. logrotate ist das Werkzeug.

5voto

Chris Taylor Punkte 50950

Ich würde einen etwas anderen Ansatz vorschlagen.

  1. Erstellen Sie eine neue temporäre Datei
  2. Kopieren Sie die erforderlichen Daten aus der Originaldatei in die temporäre Datei
  3. Beide Dateien schließen
  4. Löschen Sie die Originaldatei
  5. Umbenennen der temporären Datei in denselben Namen wie die Originaldatei

Um die Leistung des Kopiervorgangs zu verbessern, können Sie die Daten in Blöcken kopieren und mit der Größe der Blöcke spielen, um den optimalen Wert zu finden.

1voto

Thanatos Punkte 40150

Wenn dies Ihre vorherige Datei ist:

-----------------++++

Wo - ist das, was Sie nicht wollen, und + ist das, was Sie wirklich wollen, die tragbarste Art, es zu bekommen:

++++

...ist genau so, wie du gesagt hast. Lesen Sie in dem Abschnitt, den Sie wollen ( + ), Löschen/Löschen der Datei (wie bei fopen(... 'wb') or something similar und schreiben Sie das gewünschte Bit aus ( + ).

Alles, was komplizierter ist, erfordert betriebssystemspezifische Hilfe und ist nicht portabel. Leider glaube ich nicht, dass irgendein größeres Betriebssystem das, was Sie wollen, unterstützt. Vielleicht gibt es Unterstützung für "truncate nach Position X" (eine Art von head ), aber nicht die tail wie die von Ihnen geforderte Operation.

Eine solche Operation wäre schwierig zu implementieren, da unterschiedliche Blockgrößen auf Dateisystemen (wenn das Dateisystem hat eine Blockgröße) würde Probleme verursachen. Bestenfalls würde man sich auf das Schneiden an Blockgrenzen beschränken, aber das wäre schwierig. Dies ist ein so seltener Fall, dass ein solches Verfahren wahrscheinlich nicht direkt unterstützt wird.

1voto

ChrisWue Punkte 17876

Ein besserer Ansatz wäre es, die Datei nicht so groß werden zu lassen, sondern rotierende Protokolldateien mit einer bestimmten maximalen Größe pro Protokolldatei und einer maximalen Anzahl von alten Dateien zu verwenden.

0voto

Clinton Punkte 20903

Wenn Sie den Schreibvorgang kontrollieren können, möchten Sie wahrscheinlich in die Datei schreiben wie ein Ringspeicher . Auf diese Weise können Sie die letzten X Bytes der Daten behalten, ohne dass Sie das tun müssen, was Sie vorschlagen.

Selbst wenn Sie den Schreibvorgang nicht kontrollieren können, können Sie zumindest die Datei kontrollieren, in die geschrieben wird, so dass es vielleicht in eine benanntes Rohr . Sie könnten Ihr eigenes Programm an das Ende dieser benannten Pipe anhängen, das in eine Ringspeicher wie besprochen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X