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()

Answer from vallentin on Stack Overflow
🌐
Python
docs.python.org › 3 › library › io.html
io — Core tools for working with streams
The io module provides Python’s main facilities for dealing with various types of I/O. There are three main types of I/O: text I/O, binary I/O and raw I/O. These are generic categories, and various backing stores can be used for each of them. A concrete object belonging to any of these categories is called a file object.
🌐
Real Python
realpython.com › ref › stdlib › io
io | Python Standard Library – Real Python
The Python io module provides tools for dealing with various types of input/output (I/O), including reading and writing files, handling binary data, and working with streams.
🌐
W3Schools
w3schools.com › Python › ref_module_io.asp
Python io Module
Python Examples Python Compiler ... Python Bootcamp Python Training ... The io module provides Python's main facilities for dealing with streams (text, binary, buffered)....
🌐
GitHub
github.com › python › cpython › blob › main › Lib › io.py
cpython/Lib/io.py at main · python/cpython
"""The io module provides the Python interfaces to stream handling.
Author   python
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.)

🌐
GeeksforGeeks
geeksforgeeks.org › python › optimized-i-o-operations-in-python
Optimized I/O Operations in Python - GeeksforGeeks
July 23, 2025 - Python is widely used for file input/output (I/O) operations due to its simplicity and versatility. However, when working with large files or numerous Input/Output operations, optimizing file I/O becomes vital for efficient performance.
Find elsewhere
🌐
Medium
medium.com › @sanyamdubey28 › file-handling-and-working-with-the-io-package-in-python-ac2ab5c25215
File Handling and Working with the io Package in Python | by Sanyamdubey | Medium
May 2, 2025 - File handling is a fundamental aspect of programming, enabling developers to read from and write to files efficiently. In Python, the built-in io module provides a robust framework for handling file operations, offering tools to work with files ...
🌐
PyPI
pypi.org › project › Python-IO
Python-IO · PyPI
Python-IO is a Python module for working with user I/O. It has features for accepting user input and showing output.
      » pip install Python-IO
    
Published   Jan 04, 2023
Version   0.3
🌐
Cornell Virtual Workshop
cvw.cac.cornell.edu › python-intro › input-output › file-io
Cornell Virtual Workshop > Introduction to Python Programming > Input/Output > File I/O
Because an open file must be closed — even though closing typically takes place after multiple intermediate statements — a better approach to managing file access involves with the Python keyword with. A with statement is used to wrap the execution of a block with methods defined by what is known as a context manager.
🌐
AskPython
askpython.com › home › python io module: the complete practical reference
Python IO Module: The Complete Practical Reference - AskPython
February 16, 2023 - The io.open() function is a much preferred way to perform I/O operations as it is made as a high-level Pythonic interface.
🌐
Python documentation
docs.python.org › 3 › tutorial › inputoutput.html
7. Input and Output — Python 3.14.6 documentation
There are several ways to present the output of a program; data can be printed in a human-readable form, or written to a file for future use. This chapter will discuss some of the possibilities. Fa...
🌐
Reddit
reddit.com › r/learnpython › io.open vs open?
r/learnpython on Reddit: io.open vs open?
February 10, 2018 -

I saw this code used in Keras and was wondering what the benefit is of using io as opposed to just open

with io.open(path, encoding='utf-8') as f:
    text = f.read().lower()
print('corpus length:', len(text))

Here are the docs, which I looked through but couldn't figure it out:

https://docs.python.org/3/library/io.html#io.TextIOBase

P.S. Is there a shortcut to indent multiple lines to convert text into code format in a reddit post? Currently, I'm indenting each line separately.

🌐
SciPy
docs.scipy.org › doc › scipy › reference › io.html
Input and output (scipy.io) — SciPy v1.18.0 Manual
Scientific Python Forum · Search Ctrl+K · SciPy has many modules, classes, and functions available to read data from and write data to a variety of file formats. See also · NumPy IO routines · For low-level MATLAB reading and writing utilities, see scipy.io.matlab.
🌐
Temporal
learn.temporal.io › project-based tutorials › python tutorials › build a background check application with temporal and python › introduction
Introduction to the Temporal Python SDK | Learn Temporal
April 2, 2026 - python.temporal.io · The Temporal Python SDK released on March 18, 2022. The Python SDK provides access to the Temporal programming model using idiomatic Python programming paradigms.
🌐
Medium
medium.com › @AlexanderObregon › how-to-perform-file-i-o-in-python-5daec876bb27
How to Perform File I/O in Python | Medium
November 15, 2024 - File Input/Output (I/O) operations are a core part of data handling in Python. From reading configuration files to logging application activity or managing datasets, understanding file I/O allows you to interact with and manipulate stored data ...
🌐
Conda
docs.conda.io
Conda Documentation — conda-docs documentation
Conda build provides many tools that can be used to build conda packages https://docs.conda.io/projects/conda-build/en/stable/
🌐
GeeksforGeeks
geeksforgeeks.org › python › stringio-module-in-python
StringIO Module in Python - GeeksforGeeks
July 12, 2025 - StringIO is a module in Python that allows you to treat strings as file-like objects. It provides an in-memory stream for text I/O (input/output), which means you can read from and write to a string just like you would with a file, but without ...
🌐
TeachBooks
teachbooks.io › manual › features › live_code.html
Interactive content: Run Python inside your book — TeachBooks Manual
November 3, 2025 - Our book has been enable to run Python code live in the browser (thanks Max!). This extension makes code cells in your .ipynb book pages editable and executable by the reader! Opposed to the original sphinx-thebe extensions, our extension runs python in the reader’s browser and doesn’t rely on an external webserver for the python kernel.
🌐
Solomonmarvel
pythonforstarters.solomonmarvel.com › directory-and-io › python-io-module
Python IO Module | Python For Starters
January 23, 2023 - In Python, the io module provides a uniform interface for reading and writing streams of data.