Mehrere Python-Pickled-Daten gleichzeitig lesen, puffern und Zeilenumbrüche?

8

um Ihnen den Kontext zu geben:

Ich habe eine große Datei f , mehrere Gigs in der Größe. Es enthält aufeinanderfolgende Pickles von verschiedenen Objekten, die durch Ausführen von

generiert wurden

for obj in objs: cPickle.dump(obj, f)

Ich möchte die Pufferung beim Lesen dieser Datei nutzen. Was ich will, ist mehrere ausgewählte Objekte in einen Puffer zu einem Zeitpunkt zu lesen. Was ist der beste Weg, dies zu tun? Ich möchte ein Analogon von readlines(buffsize) für eingelegte Daten. In der Tat, wenn die ausgewählten Daten in der Tat newline-abgegrenzt sind, könnte man Readlines verwenden, aber ich bin mir nicht sicher, ob das stimmt.

Eine andere Option, die ich im Sinn habe, ist dumps() das gebeizte Objekt zuerst an eine Zeichenkette und dann die Zeichenketten in eine Datei zu schreiben, jede getrennt durch eine neue Zeile. Um die Datei zurück zu lesen, kann ich readlines() und loads() verwenden. Aber ich befürchte, dass ein gebeiztes Objekt den "\n" -Zeichen haben kann, und es wird dieses Dateileseschema abwerfen. Ist meine Angst unbegründet?

Eine Option ist es, es als eine riesige Liste von Objekten herauszuspülen, aber das wird mehr Speicher benötigen, als ich mir leisten kann. Das Setup kann durch Multithreading beschleunigt werden, aber ich möchte nicht dorthin gehen, bevor die Pufferung richtig funktioniert. Was ist die "beste Praxis" für Situationen wie diese.

BEARBEITEN: Ich kann auch rohe Bytes in einen Puffer einlesen und Lasten darauf aufrufen, aber ich muss wissen, wie viele Bytes dieses Puffers von Lasten verbraucht wurden, so dass ich den Kopf wegwerfen kann.

    
san 31.03.2011, 22:26
quelle

4 Antworten

5

file.readlines () gibt eine Liste des gesamten Inhalts der Datei zurück. Sie sollten ein paar Zeilen gleichzeitig lesen. Ich denke, dass dieser naive Code Ihre Daten entpacken sollte:

%Vor%

Wenn Sie die Kontrolle über das Programm haben, das die Pickles erzeugt, wähle ich eines aus:

  1. Verwenden Sie das shelve -Modul.
  2. Drucken Sie die Länge (in Bytes) jeder Beize, bevor Sie sie in die Datei schreiben, so dass Sie genau wissen, wie viele Bytes Sie jedes Mal einlesen müssen.
  3. Wie oben, aber schreiben Sie die Liste der ganzen Zahlen in eine separate Datei, so dass Sie diese Werte als Index in die Datei mit den Gurken verwenden können.
  4. Pickle eine Liste von K Objekten gleichzeitig. Schreibe die Länge dieser Beize in Bytes. Schreibe die Gurke. Wiederholen.

Übrigens, ich vermute, dass die eingebaute Pufferung von file Ihnen 99% der von Ihnen gewünschten Performance-Gewinne bringen könnte.

Wenn Sie davon überzeugt sind, dass I / O Sie blockiert, haben Sie darüber nachgedacht, mmap() auszuprobieren und das Betriebssystem das Packen in Blöcken zu einem bestimmten Zeitpunkt zu ermöglichen?

%Vor%     
Kirk Strauser 31.03.2011, 23:49
quelle
6

Sie müssen nichts tun, denke ich.

%Vor%     
quelle
2

Vielleicht möchten Sie sich das Modul shelve ansehen. Es verwendet ein Datenbankmodul wie dbm , um ein Dictionary für Objekte auf der Festplatte zu erstellen. Die Objekte selbst werden weiterhin mit Pickle serialisiert. Auf diese Weise können Sie statt einer großen Beize Sätze von Objekten gleichzeitig lesen.

    
Kamil Kisiel 31.03.2011 23:30
quelle
2

Wenn Sie einer Datei Pufferung hinzufügen möchten, öffnen Sie sie über io.open() . Hier ist ein Beispiel, das aus dem zugrunde liegenden Stream in 128K Chunks liest. Jeder Aufruf von cPickle.load() wird aus dem internen Puffer erfüllt, bis er erschöpft ist, dann wird ein weiterer Chunk aus der zugrunde liegenden Datei gelesen:

%Vor%     
samplebias 01.04.2011 00:07
quelle

Tags und Links