必须用 rb/wb 模式读写二进制文件,否则会触发文本编码/解码导致错误;rb 返回 bytes,wb 要求写入 bytes,不可混用文本方法如 readline(),应使用 read() 或 read(n)。

用 open() 读写二进制文件,必须显式指定 rb 和 wb 模式
Python 默认以文本模式打开文件,哪怕你传入的是字节数据,也会触发编码/解码流程,导致 UnicodeDecodeError 或静默损坏数据。二进制文件(如图片、PDF、加密密钥、序列化对象)必须跳过文本处理层。
关键点在于:文本模式(r/w)会自动处理换行符、尝试 UTF-8 解码;二进制模式(rb/wb)原样读写字节流,不做任何转换。
-
open('file.bin', 'rb')返回bytes对象,不是字符串 -
open('file.bin', 'wb')要求写入内容是bytes,传str会直接报TypeError: a bytes-like object is required - 不能混用:用
rb打开的文件不能调用.readline()(它依赖文本换行逻辑),而应使用.read(n)或.read()
写入二进制内容时,确保数据是 bytes 类型
常见错误是把字符串直接写进 wb 文件,比如 f.write('hello') —— 这会立刻失败。必须先编码或构造字节序列。
典型场景包括:保存 pickle 序列化结果、写入网络响应体、生成加密密钥文件。
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 字符串转
bytes:用'hello'.encode('utf-8'),但注意:编码方式不影响二进制文件语义,只是转换手段;真正重要的是你后续读取时是否一致 - 从
bytearray、struct.pack()、numpy.ndarray.tobytes()等直接获取bytes更安全 - 示例:
with open('data.bin', 'wb') as f: f.write(b'\x00\x01\x02') # 直接字节字面量 f.write(struct.pack('<I', 42)) # 打包为小端 4 字节整数
读取时别用 .readline(),优先用 .read() 或分块 .read(n)
.readline() 在二进制模式下仍会扫描 \n 字节,但它不保证文件结构中有该分隔符,容易提前截断或阻塞。尤其处理非文本协议(如自定义二进制格式、图像 header)时,行为不可控。
- 完整读取:用
f.read(),返回全部bytes;适合小文件( - 流式处理大文件:用
f.read(8192)分块读,避免内存爆掉 - 按结构解析:配合
struct.unpack()或io.BytesIO构造缓冲区,例如:with open('header.bin', 'rb') as f: raw = f.read(8) # 读前 8 字节 magic, version = struct.unpack('<II', raw) # 解包两个无符号整数
跨平台写入要注意换行符和 BOM,但二进制模式天然规避这些问题
Windows 的 \r\n、UTF-8 的 BOM(\xef\xbb\xbf)都是文本模式才介入的机制。一旦用了 wb,Python 就不会插入或转换任何字节 —— 你写什么,磁盘就存什么。
这意味着:用 wb 保存的 PNG 文件,在 Linux 上用 rb 读出来,和在 Windows 上完全一致;而如果误用 w,PNG 头部可能被篡改,导致无法识别。
- 不要试图在
wb中写'\n'来换行——它会被当作两个字符字节写入,不是系统换行符 - 如果你需要写入可读文本日志,就该用
w模式;要写原始数据,就坚持wb+bytes - 一个易忽略点:某些库(如
requests.Response.content)返回的是bytes,直接f.write(resp.content)是安全的;但resp.text是str,必须先.encode()
二进制读写最常出问题的地方,不在语法,而在意识:是否真的理解当前操作的对象是字节流,而不是“带编码的字符串”。只要守住 rb/wb 和 bytes 输入输出这两条线,99% 的乱码、截断、报错都会消失。

















