2017-05-23 2 views
0

Ich arbeite mit einer API, die eine geöffnete Binärdatei als Parameter akzeptiert und dann blockierende Lesevorgänge bis EOF ausführt.Python: Inhalt in einen offenen Stream schreiben

Anstatt eine vorhandene Datei (io.open Modus 'rb') zu öffnen, möchte ich einen Stream übergeben, den ich berechneten/konstruierten Inhalt schreibe - in der Tat will ich etwas, das konzeptionell eine unidirektionale Leitung ist, wo die Ausgabe ist wird über einen Eingabestream bereitgestellt, der mit einer geöffneten Datei austauschbar ist.

Ich habe BufferedRWPair angeschaut, aber die wenigen Beispiele, die ich finden konnte, verstoßen gegen die Warnungen, nicht dasselbe Objekt für die Eingabe- und Ausgabeseiten zu verwenden.

Wenn jemand ein passendes Beispiel oder einen besseren Vorschlag hat, ist es willkommen!

Ich habe bei BufferedRandom sah basierend auf Kommentare hier, aber ich bin offensichtlich etwas falsch, wie zu tun .... import io buf = io.BufferedRandom(io.BytesIO()) buf.write("a") buf.write("b") buf.flush() while True: print "reading" a = buf.read(1024) if not a: break print "read: {}".format(a) buf.close() Dies beendet, nachdem die zuerst lesen

Update Diese zugegebenermaßen unordentlich Beispiel zeigt die Lösung, unabhängig Lese pflegen zu müssen und Schreibpositionen

import io 
buf = io.BufferedRandom(io.BytesIO()) 
read = 0 
wrote = 0 
buf.seek(wrote) 
wrote += buf.write(b"a") 
wrote += buf.write(b"b") 
buf.seek(read) 
data = buf.read(1) 
read += len(data) 
buf.seek(wrote) 
wrote += buf.write(b"c") 
print "read: {}".format(data) 
buf.seek(read) 
data = buf.read(512) 
read += len(data) 
wrote += buf.write(b"d") 

buf.seek(wrote) 
wrote += buf.write(b"efghihjlmnop") 
while data: 
    print "read: {}".format(data) 
    buf.seek(read) 
    data = buf.read(1024) 
    read += len(data) 
buf.close() 
+0

Lesen Sie über: https://docs.python.org/3.6/library/io.html#io.Buffered Random – stovfl

+0

Nicht ganz, weil es nicht zulässt, dass ich Lese- und Schreibvorgänge im Stream interleave, ohne (ich denke) die aktuellen Lese- und Schreibpositionen selbst zu verwalten. Ich schätze, das ist eine natürliche Konsequenz des gleichen Stroms. Wird das erwartet? – user9548

Antwort

0

Kommentar: ... erlaube mir, Lese- und Schreibvorgänge in den Stream zu verschachteln, ohne ... die aktuellen Lese- und Schreibpositionen selbst zu verwalten.

Dies ist das Verhalten von io.BufferedRandom.
Aber man kann die Logik in eine eigenen class StreamRW(io.BufferedRandom),
zum Beispiel kapselt:

class StreamRW(io.BufferedRandom): 
    def __init__(self, raw): 
     super().__init__(raw) 
     self.seek(0) 

    def read(self, size=1): 
     super().seek(self.read_offset) 
     data = super().read(size) 
     self.read_offset = self.tell() 
     return data 

    def write(self, data): 
     super().seek(self.write_offset) 
     written = super().write(data) 
     self.write_offset = self.tell() 
     return written 

    def seek(self, offset): 
     super().seek(offset) 
     self.read_offset = self.write_offset = self.tell() 

#Usage: 
buf = StreamRW(io.BytesIO()) 
... 

Weitere Code wie unten, aber ohne buf.seek(0)!


Sie haben buf.seek(0) zu verwenden, um die Dateiposition zurückzuspulen.
Hinweis: Ich muss binary prefix b"" verwenden!
Dies funktioniert für mich:

import io 
buf = io.BufferedRandom(io.BytesIO()) 
buf.write(b"a") 
buf.write(b"b") 
buf.seek(0) 

while True: 
    print "reading" 
    a = buf.read(1024) 
    if not a: break 
    print "read: {}".format(a) 
buf.close() 

Ausgang:
Lese: b'ab‘

Getestet mit Python 3.4.2 und 2.7.9

+0

Nicht ganz so, als ob es mir nicht erlauben würde, Lese- und Schreibvorgänge in den Stream zu verschachteln, ohne die aktuellen Lese- und Schreibpositionen selbst zu verwalten.Ich schätze, das ist eine natürliche Konsequenz des gleichen Stroms. Wird das erwartet? – user9548

+0

Vielen Dank! Das ist eine viel weniger chaotische Version der Antwort, die ich gepostet habe, aber ich sehe, dass es wahrscheinlich funktioniert, wenn ich eine Instanz dieser neuen abgeleiteten Klasse als Stream übergebe, der gerade die Eingabedatei verwendet. Das hört sich nach dem Zweck von BufferedRWPair an, zu dem ich immer noch nicht komme, und ich werde mit Ihrem vorgeschlagenen Ansatz fortfahren. – user9548

+0

@ user9548: Lesen Was soll ich tun, wenn jemand meine Frage beantwortet? https://stackoverflow.com/help/someone-answers – stovfl

Verwandte Themen