Advanced

Reading a file as bytes

A file is bytes, and a program reads it as bytes when the text view is wrong. Reading bytes is how you handle any file whose format you know.

What you will see

0

About 2 min of reading

Try It

Read a file as bytes.

1

Write three bytes and read them back.

with open("/tmp/probe.bin", "wb") as f: f.write(b"\x00\x01\x02") with open("/tmp/probe.bin", "rb") as f: print(f.read())

Before you run it, say out loud what it will print. Then open the answer.

What it prints
b'\x00\x01\x02'
2

Count the bytes in the file.

with open("/tmp/probe.bin", "rb") as f: print(len(f.read()))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3
3

Read a two-byte header as hex.

with open("/tmp/probe.bin", "rb") as f: print(f.read(2).hex())

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0001
4

Read one byte and print its number.

with open("/tmp/probe.bin", "rb") as f: print(f.read(1)[0])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A file is a row of bytes, and reading it in binary mode hands over those exact bytes to parse by its format.
1 open in binary mode
↓
2 read gives bytes
↓
3 a header read first
↓
4 fields parsed by size
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

with open("/tmp/probe.bin", "wb") as f: sets nothing on screen
f.write(b"\x00\x01\x02") sets nothing on screen
with open("/tmp/probe.bin", "rb") as f: sets nothing on screen
print(f.read()) b'\x00\x01\x02'
Why this works
Binary mode

Opening a file in binary mode hands over the exact bytes. Text mode adds an encoding and line-ending rules, which is only right for text files.

Read by the format

A file whose format you know is read field by field: a header, then sized fields. That is how images, archives, and data files are parsed.

Examples

Open as bytes

with open("/tmp/probe.bin", "wb") as f:
    f.write(b"\x00\x01\x02")
with open("/tmp/probe.bin", "rb") as f:
    print(f.read())

Writing and reading in binary mode keeps the exact bytes. Text mode would change them.

Count the bytes

with open("/tmp/probe.bin", "rb") as f:
    print(len(f.read()))

The size of a file is the count of its bytes. Reading in binary gives that count exactly.

A header first

with open("/tmp/probe.bin", "rb") as f:
    head = f.read(2)
    print(head.hex())

Reading a fixed number of bytes first is how a format header is read. The rest follows from it.

Never guess the text

with open("/tmp/probe.bin", "rb") as f:
    print(f.read(1)[0])

Reading one byte gives its number. Treating a file as text when it is binary is the mistake this avoids.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Packing values into bytes
Previous Lesson
Packing values into bytes
Next Lesson
A string from end to end
A string from end to end →