Articles

Unterschied zwischen `open` und `io.BytesIO` in binären Strömen

Der Einfachheit halber betrachten wir vorerst das Schreiben statt das Lesen.

Wenn Sie also open() wie sagen:

with open("test.dat", "wb") as f: f.write(b"Hello World") f.write(b"Hello World") f.write(b"Hello World")

Nach der Ausführung wird eine Datei namens test.dat erstellt, die 3x Hello World enthält. Die Daten werden nicht im Speicher gehalten, nachdem sie in die Datei geschrieben wurden (es sei denn, sie werden durch einen Namen gehalten).

Nun, wenn Sie stattdessen io.BytesIO() betrachten:

with io.BytesIO() as f: f.write(b"Hello World") f.write(b"Hello World") f.write(b"Hello World")

Der Inhalt wird nicht in eine Datei, sondern in einen Puffer im Speicher geschrieben. Mit anderen Worten, in einen Teil des RAM. Im Wesentlichen wäre das Schreiben des Folgenden das Äquivalent:

buffer = b""buffer += b"Hello World"buffer += b"Hello World"buffer += b"Hello World"

Bezogen auf das Beispiel mit der with-Anweisung würde dann am Ende auch ein del buffer stehen.

Der entscheidende Unterschied ist hier die Optimierung und die Performance. Das io.BytesIO ist in der Lage, einige Optimierungen vorzunehmen, die es schneller machen als die einfache Verkettung aller b"Hello World" nacheinander.

Zum Beweis hier ein kleiner Benchmark:

  • Concat: 1,3529 Sekunden
  • BytesIO: 0.0090 Sekunden
import ioimport timebegin = time.time()buffer = b""for i in range(0, 50000): buffer += b"Hello World"end = time.time()seconds = end - beginprint("Concat:", seconds)begin = time.time()buffer = io.BytesIO()for i in range(0, 50000): buffer.write(b"Hello World")end = time.time()seconds = end - beginprint("BytesIO:", seconds)

Neben dem Performancegewinn hat die Verwendung von BytesIO anstelle der Verkettung den Vorteil, dass BytesIO anstelle eines Dateiobjekts verwendet werden kann. Sagen wir also, Sie haben eine Funktion, die ein Dateiobjekt zum Schreiben erwartet.

Der Unterschied ist, dass open("myfile.jpg", "rb") einfach den Inhalt von myfile.jpg lädt und zurückgibt, während BytesIO wiederum nur ein Puffer ist, der einige Daten enthält.

Da BytesIO nur ein Puffer ist – wenn Sie den Inhalt später in eine Datei schreiben wollten – müssten Sie folgendes tun:

buffer = io.BytesIO()# ...with open("test.dat", "wb") as f: f.write(buffer.getvalue())

Auch haben Sie keine Version erwähnt; ich verwende Python 3. Bezogen auf die Beispiele: Ich verwende die with-Anweisung statt des Aufrufs f.close()

Eine Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.