Python 文本模式与二进制模式的真实区别

根本区别在于是否自动处理编码、换行符和字节边界:文本模式自动解码/编码并标准化换行符,二进制模式原样读写字节,无任何转换。

Python 中文本模式("r""w")和二进制模式("rb""wb")的根本区别,不在“能不能读写”,而在于 是否自动处理编码、换行符和字节边界。用错模式不会立刻报错,但会在跨平台、含非 ASCII 字符或处理图像/音频等文件时悄悄出问题。

文本模式:自动解码 + 换行符标准化

文本模式下,Python 把底层字节流按指定编码(默认 UTF-8)解码成 str,写入时再把 str 编码回字节。同时,它会把系统换行符(Windows 的 \r\n、Linux/macOS 的 \n)统一转为 \n 供 Python 程序使用;写入时又按当前系统自动转回对应换行序列。

  • 读取 "hello\r\n"(Windows 文件)→ 在 Pyt

    hon 中得到 "hello\n"
  • 写入 "hi\n" → 在 Windows 上实际存为 b"hi\r\n",在 Linux 上存为 b"hi\n"
  • 若文件是 GBK 编码的中文文本,用默认 open("a.txt", "r") 会因解码失败抛 UnicodeDecodeError

二进制模式:字节原样进出,零干预

二进制模式跳过所有编码/换行处理,直接读写 bytes 对象。打开即得原始字节,写入也必须是 bytes,不猜测、不转换、不补删 \r

  • 读取 "hello\r\n" → 得到 b"hello\r\n",原封不动
  • 写入 b"abc\x00\xff" → 精确写入这 5 个字节,无任何修饰
  • 适合处理图片、PDF、ZIP、加密数据等——它们根本不是文本,也没有“换行”概念

混用模式的典型陷阱

错误往往发生在“以为是文本,其实是二进制”或“想省事用文本处理非 UTF-8 数据”时:

  • open("image.jpg", "r").read() → 解码失败(UnicodeDecodeError),因为 JPG 是纯字节
  • open("log.txt", "wb").write("done\n") → 类型错误(TypeError: a bytes-like object is required),因为 "done\n"str,不是 bytes
  • 在 Windows 上用文本模式读取由 Linux 生成的 UTF-8 文件(无 BOM),又没指定 encoding="utf-8" → 可能被误判为 CP1252,导致中文乱码

怎么选?看数据本质,不看文件扩展名

决定模式的关键是内容,不是后缀:

  • 用二进制模式:图片(.png/.jpg)、压缩包(.zip/.tar)、可执行文件(.exe/.so)、序列化数据(.pkl)、网络抓包(.pcap)
  • 用文本模式:代码(.py/.js)、配置(.json/.toml)、日志(.log)、纯文本文档(.txt),且明确知道其编码(推荐显式传 encoding 参数)
  • 不确定编码?先用二进制模式读前几字节判断 BOM 或用 chardet 探测,再选文本模式重开