Python Basics: Inspect Fixed Byte Ranges with mmap
A binary file can be inspected through a memory mapping without first reading the entire file into a Python bytes object. This example contrasts a read-only mapping with a private copy-on-write mapping.
Prepare a scratch directory
Tested on Linux with CPython 3.12.14. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. Run Python without -O so assertions remain enabled. The examples use only controlled local data; generated fixture directories are cleaned automatically.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-mmap.py:
import mmap
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "records.bin"
path.write_bytes(b"HEAD|alpha|beta")
with path.open("rb") as source:
with mmap.mmap(source.fileno(), 0, access=mmap.ACCESS_READ) as view:
print("Header:", view[:4].decode("ascii"))
print("beta starts at:", view.find(b"beta"))
assert view[5:10] == b"alpha"
with mmap.mmap(source.fileno(), 0, access=mmap.ACCESS_COPY) as private:
private[:4] = b"TEST"
print("Private header:", private[:4].decode("ascii"))
assert path.read_bytes() == b"HEAD|alpha|beta"
print("Disk header:", path.read_bytes()[:4].decode("ascii"))Run it:
python3 -B demonstrate-mmap.pyObserved output:
Header: HEAD
beta starts at: 11
Private header: TEST
Disk header: HEADRead the result
Length zero maps the current file size. Slice positions count bytes, and find returns a byte offset. ACCESS_COPY lets the second mapping change its private view while the file keeps its original header.
Apply it carefully
The fixture is nonempty and never resized while mapped. Do not assume another process can safely truncate a mapped file. A slice still creates a bytes result; a mapping does not make every operation allocation-free. Close the mapping before closing its file or deleting the fixture.
The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.
Clean up
Remove the saved source, return to the starting directory, then remove the empty practice directory:
rm -- demonstrate-mmap.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect its remaining contents rather than deleting unknown files.
Acknowledgements
This post was created with assistance from AI.