🌐
DigitalOcean
digitalocean.com › community › tutorials › python-io-bytesio-stringio
Python io.BytesIO and io.StringIO: Memory File Guide | DigitalOcean
August 3, 2022 - Just like what we do with variables, data can be kept as bytes in an in-memory buffer when we use the io module’s Byte IO operations. Here is a sample program to demonstrate this: import io stream_str = io.BytesIO(b"JournalDev Python: \x00\x01") print(stream_str.getvalue())
🌐
Python
docs.python.org › 3 › library › io.html
io — Core tools for working with streams
Its subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer raw binary streams that are writable, readable, and both readable and writable, respectively. BufferedRandom provides a buffered interface to seekable streams. Another BufferedIOBase subclass, BytesIO, is a stream of in-memory bytes.
🌐
AskPython
askpython.com › home › python io module: the complete practical reference
Python IO Module: The Complete Practical Reference - AskPython
February 16, 2023 - Here, we can keep our data in the form of bytes (b''). When we use io.BytesIO, the data is held in an in-memory buffer. We can get an instance to the byte stream using the constructor: import io bytes_stream = io.BytesIO(b'Hello from ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › stringio-and-bytesio-for-managing-data-as-file-object
Stringio And Bytesio For Managing Data As File Object - GeeksforGeeks
July 24, 2025 - ... from io import BytesIO # Create a new BytesIO object binary_buffer = BytesIO() # Hexadecimal representation of "Hello" binary_buffer.write(b'\x48\x65\x6C\x6C\x6F') # Get the contents of the buffer as bytes result_bytes = binary_buffer.getvalue() ...
🌐
Medium
medium.com › @abhishekshaw020 › understanding-bytesio-handling-in-memory-files-like-a-pro-e1b767339468
Understanding BytesIO: Handling In-Memory Files Like a Pro | by Abhishek Shaw | Medium
March 31, 2025 - First, let’s create a simple in-memory file and write some text to it: from io import BytesIO # Create a new BytesIO object memory_file = BytesIO() # Write data (must be in bytes, so we encode it) memory_file.write(b"Hello, this is an in-memory ...
🌐
Reddit
reddit.com › r/learnpython › vs
r/learnpython on Reddit: <class 'bytes'> vs <class '_io.BytesIO'>
December 1, 2022 -

Hello all,

I'm trying to wrap my head around the practical differences between:

<class 'bytes'> and <class '_io.BytesIO'>.

I read through the documentation:

https://docs.python.org/3/library/io.html?highlight=bytesio#binary-i-o

Binary I/O (also called buffered I/O) expects bytes-like objects and produces bytes objects. No encoding, decoding, or newline translation is performed. This category of streams can be used for all kinds of non-text data, and also when manual control over the handling of text data is desired.

It provides some examples:

The easiest way to create a binary stream is with open() with 'b' in the mode string:

and

f = io.BytesIO(b"some initial binary data: \x00\x01")

So I read all this, but so what? Why would you use the io.BytesIO data type over a standard bytes data type?

EDIT: Let me provide some additional context that I just discovered after reading the documentation on lxml.

https://lxml.de/parsing.html#parsing-html

I'm using the requests object and parsing the results with lxml. Here is the example code:

from io import BytesIO
from lxml import etree
#* etree - https://lxml.de/parsing.html
#? etree stands for element tree

import requests

#? Need to know concepts
#?  What are bytes
#?  HTTP status codes
#?  HTTP methods (GET. POST, PUT, DELETE)
#?  bytes - https://docs.python.org/3/library/stdtypes.html?highlight=bytes#bytes-objects

url = 'http://localhost'
#! The URL https://nostarch.com/ doesn't seem to work

resp = requests.get(url=url)
html_bytes = resp.content
parser = etree.HTMLParser()
content = etree.parse(BytesIO(html_bytes), parser=parser)

print(type(html_bytes))
print(type(BytesIO(html_bytes)))

for link in content.findall('//a'):
    print(f"{link.get('href')} -> {link.text}")

Kind regards

🌐
Confessions of a Data Guy
confessionsofadataguy.com › home › you have to try this… from io import stringio, bytesio
You Have to Try This... from io import StringIO, BytesIO - Confessions of a Data Guy
January 2, 2021 - One minor detail to remember about a StringIO/BytesIO is that when created, it acts like an already opened file! Let’s look at some examples of how this could work. Simplistic, but to the point. from io import StringIO, BytesIO import csv in_memory_file = StringIO() csv_writer = csv.writer(in_memory_file) csv_writer.writerows([[1, 2, 3], [4, 5, 6]]) in_memory_file.seek(0) for row in in_memory_file: print(row)
🌐
Mellowd
mellowd.dev › posts › using-io-bytesio
Using io.BytesIO() with Python | mellowd.dev
May 16, 2019 - #!/usr/bin/env python3 import io import matplotlib import matplotlib.pyplot as plt import numpy as np t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2 * np.pi * t) fig, ax = plt.subplots() ax.plot(t, s) ax.set(xlabel='time (s)', ylabel='voltage (mV)', title='About as simple as it gets, folks') ax.grid() b = io.BytesIO() plt.savefig(b, format='png') plt.close()
Find elsewhere
🌐
Code-learner
code-learner.com › home › python stringio and bytesio example
Python StringIO And BytesIO Example ·
March 21, 2021 - We create a BytesIO object and then write some bytes data into it. Please note that instead of writing a string, you write utf-8 encoded bytes with the BytesIO object. # Import BytesIO module. >>> from io import BytesIO # Create a BytesIO object. >>> bytIO = BytesIO() # Write bytes that are ...
🌐
Python
wiki.python.org › moin › BytesIO
BytesIO - Python Wiki
April 28, 2011 - 1 import array 2 def bytes(seq=()): 3 return array.array('B', seq) There is no BytesIO.getvalue() method because it's not needed. Instead, just keep a reference to the underlying buffer. This works with lists and arrays, as well as bytes objects, but it's sort of a coincidence, rather than an actual design goal...
🌐
PyPI
pypi.org › project › bytesbufio
bytesbufio · PyPI
July 12, 2020 - Python :: 3 · Report project as malware · Test that shows the problem · "Fixed" implementation - BytesBufferIO · pip install bytesbufio · import io from bytesbufio import BytesBufferIO bytesbuf = BytesBufferIO() with io.TextIOWrapper(bytesbuf, ...
      » pip install bytesbufio
    
Published   Jul 12, 2020
Version   1.0.3
🌐
Medium
medium.com › @sarthakshah1920 › harnessing-the-power-of-in-memory-buffers-with-bytesio-0ac6d5493178
Harnessing the Power of In-Memory Buffers with BytesIO | by Sarthak Shah | Medium
December 24, 2023 - In the provided code snippet, we use the BytesIO module to create an in-memory buffer and populate it with file content. Let's break down the steps involved in this process: We start by importing the BytesIO class from the io module.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-stringio-and-bytesio-compared-with-open
Python Stringio and Bytesio Compared With Open() - GeeksforGeeks
July 23, 2025 - ... from io import BytesIO bio = BytesIO() # Binary data representing "hello GFG" binary_data = b'\x68\x65\x6C\x6C\x6F\x20\x47\x46\x47' for _ in range(3): bio.write(binary_data) bio.seek(0) # Read the content of the BytesIO buffer read_data ...
🌐
Andrew Wheeler
andrewpwheeler.com › 2022 › 11 › 02 › using-io-objects-in-python-to-read-data
Using IO objects in python to read data | Andrew Wheeler
November 2, 2022 - # Example 2, grabbing zipped contents import zipfile from io import BytesIO census_url = 'https://www2.census.gov/programs-surveys/acs/summary_file/2019/data/2019_5yr_Summary_FileTemplates.zip' req = requests.get(census_url) # Can use BytesIO for this content zf = zipfile.ZipFile(BytesIO(req.content))
🌐
Python⇒Speed
pythonspeed.com › articles › bytesio-reduce-memory-usage
The surprising way to save memory with BytesIO
February 27, 2025 - Python’s io.BytesIO allows you to create a file-like object that stores bytes in memory: from io import BytesIO f = BytesIO() f.write(b"hello ") f.write(b"world") f.seek(0) assert f.read() == b"hello world"
🌐
Pynerds
pynerds.com › io-bytesio-in-python
io.BytesIO in Python
Disclaimer: References to any specific company, product or services on this Site are not controlled by GoDaddy.com LLC and do not constitute or imply its association with or endorsement of third party advertisers
🌐
ProgramCreek
programcreek.com › python › example › 1734 › io.BytesIO
Python Examples of io.BytesIO
def screenshot(self, png_filename=None, format='pillow'): """ Screenshot with PNG format Args: png_filename(string): optional, save file name format(string): return format, "raw" or "pillow” (default) Returns: PIL.Image or raw png data Raises: WDARequestError """ value = self.http.get('screenshot').value raw_value = base64.b64decode(value) png_header = b"\x89PNG\r\n\x1a\n" if not raw_value.startswith(png_header) and png_filename: raise WDARequestError(-1, "screenshot png format error") if png_filename: with open(png_filename, 'wb') as f: f.write(raw_value) if format == 'raw': return raw_value elif format == 'pillow': from PIL import Image buff = io.BytesIO(raw_value) return Image.open(buff) else: raise ValueError("unknown format") Example #21 ·
Top answer
1 of 2
208

For simplicity's sake, let's consider writing instead of reading for now.

So when you use open() like say:

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

After executing that a file called test.dat will be created, containing 3x Hello World. The data wont be kept in memory after it's written to the file (unless being kept by a name).

Now when you consider io.BytesIO() instead:

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

Which instead of writing the contents to a file, it's written to an in memory buffer. In other words a chunk of RAM. Essentially writing the following would be the equivalent:

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

In relation to the example with the with statement, then at the end there would also be a del buffer.

The key difference here is optimization and performance. io.BytesIO is able to do some optimizations that makes it faster than simply concatenating all the b"Hello World" one by one.

Just to prove it here's a small benchmark:

  • Concat: 1.3529 seconds
  • BytesIO: 0.0090 seconds

import io
import time

begin = time.time()
buffer = b""
for i in range(0, 50000):
    buffer += b"Hello World"
end = time.time()
seconds = end - begin
print("Concat:", seconds)

begin = time.time()
buffer = io.BytesIO()
for i in range(0, 50000):
    buffer.write(b"Hello World")
end = time.time()
seconds = end - begin
print("BytesIO:", seconds)

Besides the performance gain, using BytesIO instead of concatenating has the advantage that BytesIO can be used in place of a file object. So say you have a function that expects a file object to write to. Then you can give it that in-memory buffer instead of a file.

The difference is that open("myfile.jpg", "rb") simply loads and returns the contents of myfile.jpg; whereas, BytesIO again is just a buffer containing some data.

Since BytesIO is just a buffer - if you wanted to write the contents to a file later - you'd have to do:

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

Also, you didn't mention a version; I'm using Python 3. Related to the examples: I'm using the with statement instead of calling f.close()

2 of 2
42

Using open opens a file on your hard drive. Depending on what mode you use, you can read or write (or both) from the disk.

A BytesIO object isn't associated with any real file on the disk. It's just a chunk of memory that behaves like a file does. It has the same API as a file object returned from open (with mode r+b, allowing reading and writing of binary data).

BytesIO (and it's close sibling StringIO which is always in text mode) can be useful when you need to pass data to or from an API that expect to be given a file object, but where you'd prefer to pass the data directly. You can load your input data you have into the BytesIO before giving it to the library. After it returns, you can get any data the library wrote to the file from the BytesIO using the getvalue() method. (Usually you'd only need to do one of those, of course.)