The io
module in the standard library provides functions and classes for handling input and output operations. In this article we will focus on the BytesIO
class.
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.
To use the class we will first need to import it in our program, as shown below:
from io import BytesIO #import the class
print(BytesIO)
Basic Usage
The BytesIO
constructor has the following syntax:
BytesIO(initial_bytes = b'')
The initial_bytes
parameter specifies the initial bytes contents of the created BytesIO
object. If initial_bytes
is not given, an empty BytesIO
will be created.
initialize a BytesIO object
from io import BytesIO
data = b'Hello, World'
stream = BytesIO(data)
print(stream.getvalue()) #read from the stream
stream.close()
In the above example we created a bytes stream with initial bytes data, the b
prefix indicates that the string should be treated as a bytes literal rather than a regular string.
The stream.getvalue()
method returns the entire contents of the bytes stream as a bytes object.
After calling the close()
method, the stream cannot be read from or written to. We can automate calling of this method by using the ByteIO
object as a context manager i.e using with statement. This way the above example will look as follows:
from io import BytesIO
data = b'Hello, World'
with BytesIO(data) as stream:
print(stream.getvalue()) #read from the stream
#the stream is now closed.
Reading and Writing bytes data
We can perform various operations on the BytesIO
stream, just like we would on a regular file object.
reading bytes
The read()
method to reads and returns a specified number of bytes from the stream starting from the current position of the stream "cursor".
use read() to read from the stream
from io import BytesIO
data = b'Hello, World!'
with BytesIO(data) as stream:
stream = BytesIO(data)
stream.seek(0)
print(stream.read(5)) #read 5 bytes from the stream
Note that in the above example, before calling the read()
method, we first called the seek()
method which moves the current position in the file to the beginning (position 0
). This ensures that when we call the read()
method, it will start reading the file from the beginning. Otherwise, it would start reading from wherever the 'cursor' position is, which in the above case is in the end of the file.
The readline()
methods reads bytes until it meets the end of line character. Consider the following example:
from io import BytesIO
data = b"Hello, World!\nWelcome to Pynerds."
with BytesIO(data) as stream:
stream.seek(0)
print('line1: ', stream.readline()) #reads a single line
print('line2: ', stream.readline()) #reads another line
To read multiple lines at once , we can use the readlines()
method, which returns a list of all lines in the stream starting from the position of the "cursor".
from io import BytesIO
data = b"Hello, World!\nWelcome to Pynerds."
stream = BytesIO(data)
stream.seek(0)
print(stream.readlines()) #read all lines
Writing to the stream
The write()
method writes the specified bytes into the stream, starting from the current point of the "cursor". It has the following syntax:
stream.write(data)
write to the stream
from io import BytesIO
with BytesIO() as stream:
stream.write(b'Hello, World!\n')
stream.write(b'Welcome to Pynerds.')
print(stream.getvalue()) #get the contents
To write multiple lines at once you can use the writelines()
method. The method takes an iterable containing the lines of bytes to be written.
from io import BytesIO
lines = [b'Hello, World\n', b'Welcome to Pynerds']
with BytesIO() as stream:
stream.writelines(lines)
print(stream.getvalue()) #get the contents
Note that the writelines()
method does not add the end of line character between the lines, you have to do that yourself.
Other BytesIO methods and attributes
In addition to the methods we have discussed, BytesIO
objects contains other methods, some of them are shown in the following table:
readable() |
Returns True if the BytesIO stream can be read from. Otherwise False . |
seekable() |
Returns True if the stream can be seeked. Otherwise False |
writable() |
Returns True if the stream can be written to. Otherwise False . |
seek() |
Change the positions of the stream 'cursor' to the specified position. Defaults to 0, which is the beginning of the stream. |
tell() |
Returns the current position of the stream 'cursor'. |
truncate() |
Truncate the stream to a given size. |