You need to seek back to the beginning of the file after writing the initial in memory file...

myio.seek(0)
Answer from mgilson on Stack Overflow
🌐
Python
docs.python.org › 3 › library › io.html
io — Core tools for working with streams
January 30, 2026 - 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.
🌐
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 - Think of BytesIO as a virtual file that lives in your computer’s memory (RAM) instead of your hard drive. It lets you read and write data just like a normal file, but everything stays in memory—fast, efficient, and no cleanup required!
🌐
TechOverflow
techoverflow.net › 2019 › 07 › 24 › how-to-write-bytesio-content-to-file-in-python
How to write BytesIO content to file in Python | TechOverflow
July 23, 2019 - """ with open(filename, "wb") as outfile: # Copy the BytesIO stream to the output file outfile.write(bytesio.getbuffer()) write_bytesio_to_file("out.txt", myio)
🌐
DigitalOcean
digitalocean.com › community › tutorials › python-io-bytesio-stringio
Python io.BytesIO and io.StringIO: Memory File Guide | DigitalOcean
August 3, 2022 - It does not return a file object; the returned value will not have read() or write() functions. Overall, io.open() function is just a wrapper over os.open() function. The os.open() function just also sets default config like flags and mode too while io.open() doesn’t to it and depends on ...
🌐
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 - In this example, a new BytesIO object named binary_buffer is created to emulate an in-memory file for binary data. The hexadecimal representation of the string "Hello" is written to the buffer using write.
🌐
Mellowd
mellowd.dev › python › using-io-bytesio
Using io.BytesIO() with Python - mellowd.dev
#!/usr/bin/env python3 import io ... b = io.BytesIO() plt.savefig(b, format='png') plt.close() b is now an in-memory object that can be used wherever a file is used. Attach it to your tweet and you’re set. If you do need to now dump this image to storage you can still do that. with open("image.png", "wb") as f: f.write(b.re...
Find elsewhere
🌐
ProgramCreek
programcreek.com › python › example › 1734 › io.BytesIO
Python Examples of io.BytesIO
:rtype : ``str`` ''' writer = avro.io.DatumWriter(avro.schema.parse(AVSC)) rawbytes = io.BytesIO() try: writer.write({ list.__name__: value }, avro.io.BinaryEncoder(rawbytes)) return rawbytes except avro.io.AvroTypeException: logging.getLogger('SPOT.INGEST.COMMON.SERIALIZER')\ .error('The type of ``{0}`` is not supported by the Avro schema.'
Top answer
1 of 4
98
# Create an example
from io import BytesIO
bytesio_object = BytesIO(b"Hello World!")

# Write the stuff
with open("output.txt", "wb") as f:
    f.write(bytesio_object.getbuffer())
2 of 4
49

It would be helpful if you supplied the library you were using to work on excel files, but here's a buckshot of solutions, based on some assumptions I'm making:

  • Based on the first paragraph in the io module's documentation, it sounds like all the concrete classes- including BytesIO- are file-like objects. Without knowing what code you've tried so far, I don't know if you have tried passing the BytesIO to the module you're using.
  • On the off chance that doesn't work, you can simply convert BytesIO to a another io Writer/Reader/Wrapper by passing it to the constructor. Example:

.

import io

b = io.BytesIO(b"Hello World") ## Some random BytesIO Object
print(type(b))                 ## For sanity's sake
with open("test.xlsx") as f: ## Excel File
    print(type(f))           ## Open file is TextIOWrapper
    bw=io.TextIOWrapper(b)   ## Conversion to TextIOWrapper
    print(type(bw))          ## Just to confirm 
  • You may need to check which kind of Reader/Writer/Wrapper is expected by the module you're using to convert the BytesIO to the correct one
  • I believe I have heard that (for memory reasons, due to extremely large excel files) excel modules do not load the entire file. If this ends up meaning that what you need is a physical file on the disk, then you can easily write the Excel file temporarily and just delete it when you're done. Example:

.

import io
import os

with open("test.xlsx",'rb') as f:
    g=io.BytesIO(f.read())   ## Getting an Excel File represented as a BytesIO Object
temporarylocation="testout.xlsx"
with open(temporarylocation,'wb') as out: ## Open temporary file as bytes
    out.write(g.read())                ## Read bytes into file

## Do stuff with module/file
os.remove(temporarylocation) ## Delete file when done

I'll hope that one of these points will solve your problem.

🌐
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 - file_content = "This is a sample text file content." file_buffer = BytesIO() We write the file content to the in-memory buffer using the write method. In this case, we encode the text content to bytes using the encode() method before writing ...
🌐
Python⇒Speed
pythonspeed.com › articles › bytesio-reduce-memory-usage
The surprising way to save memory with BytesIO
February 27, 2025 - How does this work? BytesIO is using copy-on-write. Internally, it keeps a reference to the new bytes object returned from getvalue(). So long as you don’t write to the BytesIO, any reads can happen off the same memory.
🌐
Python Assets
pythonassets.com › posts › what-is-io-bytesio-useful-for
What Is `io.BytesIO` Useful For? | Python Assets
July 19, 2024 - io.BytesIO is a standard class ... only in our program's memory. This means you can read from and write to it just like a file, but without creating any actual files on disk....
🌐
Webkul
webkul.com › home › python: using stringio and bytesio for managing data as file object
Python: Using StringIO and BytesIO for managing data as file object - Webkul Blog
October 1, 2019 - io.BytesIO requires a bytes string. StringIO.StringIO allows either Unicode or Bytes string. cStringIO.StringIO requires a string that is encoded as a bytes string. Here is a simple example using io module · >>> import io >>> string_out = io.StringIO() >>> string_out.write('A sample string which we have to send to server as string data.') 63##Length of data >>> string_out.getvalue() 'A sample string which we have to send to server as string data.'
Top answer
1 of 2
207

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

🌐
Pynerds
pynerds.com › io-bytesio-in-python
io.BytesIO in Python
March 28, 2024 - The BytesIO class is used for creating in-memory byte streams that can be used as a file object. The created BytesIO object( commonly reffered to as a stream) has a file-like API, with methods like read(), write(), readlines() and other file methods.
🌐
GitHub
github.com › bastibe › python-soundfile › issues › 315
Is it possible to write to BytesIO? · Issue #315 · bastibe/python-soundfile
September 22, 2021 - I get a format not recognized error when I try to use a BytesIO object as the file parameter.
Author   cbhower