Frage

Ich habe eine Anwendung, die einige große Protokolldateien> 500MB erzeugt.

Ich habe einige Dienstprogramme in Python geschrieben, die ich erlaubt, schnell die Protokolldatei zu durchsuchen und Daten von Interesse zu finden. Aber ich nun einige Datensätze erhalten, wo die Datei zu groß ist alles in den Speicher zu laden.

Ich möchte also einmal das Dokument scannen, um einen Index erstellen und dann nur den Abschnitt des Dokuments in den Speicher laden, die ich zu einem Zeitpunkt suchen.

Dies funktioniert für mich, wenn ich eine ‚Datei‘ öffnen lesen sie eine Zeile zu einem Zeitpunkt und speichert den Offset mit von file.tell (). Ich kann dann später in diesem Abschnitt der Datei wieder mit file.seek (Offset, 0).

Mein Problem ist jedoch, dass ich UTF-8 in den Protokolldateien hat, damit ich sie mit der Codec-Modul öffnen muß (codecs.open(<filename>, 'r', 'utf-8')). Mit dem resultierenden Objekt kann ich anrufen will und sagen, aber sie nicht zusammenpassen.

Ich gehe davon aus, dass Codecs gewisse Puffer tun muss, oder vielleicht gibt es Charakter zählt anstelle von Bytes aus sagen?

Gibt es eine Möglichkeit, um dieses?

War es hilfreich?

Lösung

Wenn das stimmt, das klingt wie ein Bug oder Begrenzung des Codecs Modul, wie es ist wahrscheinlich verwirrend Byte und Zeichen-Offsets.

Ich würde die reguläre open() Funktion verwenden, um die Datei zu öffnen, dann seek() / tell() geben Sie Offsets Byte, das immer konsistent ist. Jedes Mal, wenn Sie lesen möchten, verwenden Sie f.readline().decode('utf-8').

Beachten Sie jedoch, dass die f.read()-Funktion können Sie in der Mitte eines Multi-Byte-Zeichen landen, so dass ein UTF-8-Decodierfehler erzeugen. readline() wird immer funktionieren.

Dieser behandelt nicht transparent die Byte-Reihenfolge-Marke für Sie, aber die Chancen sind Ihre Log-Dateien haben keine Stücklisten sowieso.

Andere Tipps

Für UTF-8, Sie nicht wirklich benötigen, um die Datei mit codecs.open zu öffnen. Stattdessen ist es zuverlässig die Datei als Byte-String zu lesen, zuerst, und nur dann einen individuellen Abschnitt entschlüsseln (auf der Saite die .decode Methode aufrufen). die Datei in Zeile Grenzen zu brechen ist sicher; die einzige unsichere Art und Weise spalten sie in der Mitte eines Multi-Byte-Zeichen sein würde (was man von seinem Byte-Wert> 128 erkennen kann).

Viel von dem, was mit UTF8 in Python geht weiter macht Sinn, wenn man sieht, wie es in Python 3. In Ihrem Fall getan wurde, wird es recht macht ein bisschen mehr Sinn, wenn Sie die Dateien Kapitel in Tauchen Sie ein in Python lesen 3 : http://diveintopython3.org/files.html

Die kurze davon ist jedoch, dass file.seek und file.tell Arbeit mit Byte-Positionen, während Unicode-Zeichen mehr Bytes aufnehmen können. Wenn Sie also tun:

f.seek(10)
f.read(1)
f.tell()

Sie können ganz einfach etwas anderes als 17 bekommen, je nachdem, welche Länge die ein Zeichen, das Sie lesen war.

Update: Sie können auf dem Objekt nicht suchen / tell von codec.open () zurückgegeben wird. Sie müssen eine normale Datei verwenden, und die Saiten zu dekodieren nach dem Lesen Unicode.

Ich weiß nicht, warum es nicht funktioniert, aber ich kann es nicht funktionieren. Die Such scheint nur einmal zu arbeiten, zum Beispiel. Dann müssen Sie die Datei schließen und wieder öffnen, was natürlich nicht sinnvoll.

Die tell verwenden Zeichenpositionen nicht, aber nicht Sie zeigen, wo Ihre Position im Stream (aber wahrscheinlich, wo das zugrunde liegende Dateiobjekt ist von der Festplatte beim Lesen).

So wahrscheinlich wegen irgendeiner Art der zugrunde liegenden Pufferung, man kann es nicht tun. Aber deocding nach der Lektüre nur gut funktioniert, so dass für gehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top