How the write(), read() and getvalue() methods of Python io.BytesIO work?

Robert picture Robert · Nov 26, 2018 · Viewed 15.7k times · Source

I'm trying to understand the write() and read() methods of io.BytesIO. My understanding was that I could use the io.BytesIO as I would use a File object.

import io
in_memory = io.BytesIO(b'hello')
print( in_memory.read() )

The above code will return b'hello' as expected, but the code below will return an empty string b''.

import io
in_memory = io.BytesIO(b'hello')
in_memory.write(b' world')
print( in_memory.read() )

My questions are:

-What is io.BytesIO.write(b' world') doing exactly?

-What is the difference between io.BytesIO.read() and io.BytesIO.getvalue()?

I assume that the answer is related to io.BytesIO being a stream object, but the big picture is not clear to me.

Answer

johnpaton picture johnpaton · Nov 26, 2018

The issue is that you are positioned at the end of the stream. Think of the position like a cursor. Once you have written b' world', your cursor is at the end of the stream. When you try to .read(), you are reading everything after the position of the cursor - which is nothing, so you get the empty bytestring.

To navigate around the stream you can use the .seek method:

>>> import io
>>> in_memory = io.BytesIO(b'hello', )
>>> in_memory.write(b' world')
>>> in_memory.seek(0)  # go to the start of the stream
>>> print(in_memory.read())
b' world'

Note that, just like a filestream in write ('w') mode, the initial bytes b'hello' have been overwritten by your writing of b' world'.

.getvalue() just returns the entire contents of the stream regardless of current position.