人人都会AI编程

12.2 文件模式:读、写、追加、二进制模式、文本模式

更新时间:2026-07-12

open() 函数的第二个参数是模式字符串,它决定了你能对文件做什么,以及数据以什么形式读写。模式选错,轻则报错,重则误删数据,所以必须搞清楚。

基础模式字符

| 字符 | 含义 |
|------|------|
| r | 读取(默认),文件必须存在,否则报 FileNotFoundError |
| w | 写入,会清空已有内容,文件不存在则创建 |
| x | 排他性创建,文件已存在则报错,适合避免意外覆盖 |
| a | 追加,从文件末尾继续写入,文件不存在则创建 |
| b | 二进制模式,与上面字符组合使用(如 rbwb) |
| t | 文本模式(默认),与上面字符组合使用(如 rt 就等于 r) |
| + | 更新模式,同时支持读写,与 r/w/a 组合使用 |

实际使用中,模式字符串由这些字符组合而成。最常用的几个组合是:

1. 只读:'r' (默认文本模式)

with open('data.txt', 'r', encoding='utf-8') as f:
    content = f.read()      # 一次性读入全部内容
    # 或逐行读取
    for line in f:
        print(line.strip())
  • 文件不存在会报错。
  • 不写 'r''t',因为它们是默认值,open('data.txt') 等价于 open('data.txt', 'rt')

2. 只写:'w'

with open('output.txt', 'w', encoding='utf-8') as f:
    f.write('Hello\n')
    f.write('World\n')
  • 谨慎:每次用 'w' 打开,文件的已有内容立刻被清空。
  • 文件不存在会自动创建。
  • 适合从头生成新文件。

3. 追加:'a'

with open('log.txt', 'a', encoding='utf-8') as f:
    f.write(f'错误发生时间:{datetime.now()}\n')
  • 写入的数据会追加到文件末尾,不清空原有内容
  • 文件不存在会自动创建。
  • 常用于日志文件、持续记录的监控数据。

4. 二进制模式:'rb' / 'wb'

处理图片、音频、视频、PDF 等非文本文件,必须用二进制模式。

# 复制图片
with open('source.jpg', 'rb') as src, open('copy.jpg', 'wb') as dst:
    dst.write(src.read())   # 按字节复制
  • 二进制模式下,读取返回的是 bytes 对象,而不是字符串。
  • 不能指定 encoding 参数,因为二进制数据就是原始字节流。

5. 读写组合:'r+' / 'w+' / 'a+'

  • 'r+':读写模式,文件必须存在,写入从文件开头覆盖,不会清空原内容。
  • 'w+':读写模式,但会清空已有文件;文件不存在则创建。
  • 'a+':读写模式,写入追加到末尾,可以读取到原内容,但读取位置需要手动定位(因为打开时指针在末尾)。
with open('data.txt', 'r+', encoding='utf-8') as f:
    content = f.read()
    f.write('\n追加一行')

实际项目中,'r+' / 'w+' 用得较少,因为同时读写时指针位置容易混乱。多数场景下,先读后写、或先写后读、用不同句柄操作更清晰。

文本模式 vs 二进制模式的选择

  • 文本模式t):默认,读写数据是字符串,会根据平台自动处理换行符(Windows 为 \r\n,Linux/macOS 为 \n),需要指定编码(如 utf-8)。
  • 二进制模式b):读写原始字节,不做换行符转换,无法指定编码。所有非文本文件都必须用二进制模式,否则图片文件会被破坏。

简单记忆:只要你读写的是 .txt.csv.json 这类纯文本文件,就用文本模式;处理 .jpg.pdf.zip 等文件,直接用二进制模式。