跳到主要内容

文件读写

读写文件是最常见的 IO 操作;Python 内置读写文件的函数,用法与 C 兼容。

1. 前提:文件对象由操作系统提供

  • 磁盘上读写文件由操作系统提供,现代 OS 不允许普通程序直接操作磁盘。
  • 读写文件 = 请求 OS 打开一个文件对象(文件描述符),然后通过 OS 接口读数据写数据

2. 读文件

open() 与 close()

  • open(路径, 'r'):以模式打开文件对象;'r' 表示读。文件不存在会 FileNotFoundError(IOError)。
  • f.read()一次读取全部内容到内存,返回 str
  • f.close()必须关闭文件;文件对象占用 OS 资源,OS 能打开的文件数有限。

保证关闭:try...finally 与 with

  • 读写可能产生 IOError,出错时后面的 f.close() 可能不执行;用 try...finally 可保证无论是否出错都关闭。
  • 推荐:用 with open(...) as f:,自动调用 close(),代码更简洁。
with open('/path/to/file', 'r') as f:
print(f.read())

按需读取:read(size)、readline、readlines

  • read() 一次性读全部,大文件会占满内存;可按需选择:
    • read(size):每次最多读 size 字节,适合大文件。
    • readline():每次读一行
    • readlines():一次读全部并按返回 list
场景推荐
文件很小read() 一次性读最方便
不确定文件大小read(size) 反复调用较安全
配置文件(按行处理)readlines() 最方便
for line in f.readlines():
print(line.strip()) # 去掉末尾 '\n'

3. file-like Object

  • open() 返回的这种有 read() 方法的对象,统称 file-like Object
  • 可以是文件内存字节流网络流、自定义流等;不要求从特定类继承,只要有 read() 就行。
  • StringIO 就是在内存中创建的 file-like Object,常用作临时缓冲。

4. 二进制文件

  • 默认是读文本文件(UTF-8)。读二进制文件(图片、视频等)用 'rb' 模式打开;f.read() 返回 bytes(如 b'\xff\xd8...')。
f = open('/path/to/test.jpg', 'rb')
f.read() # 十六进制表示的字节

5. 字符编码

  • 非 UTF-8 的文本文件,给 open()encoding 参数,如 encoding='gbk'
  • 遇到编码不规范可能 UnicodeDecodeErroropen() 可传 errors 参数,如 errors='ignore' 忽略错误。
f = open('/path/to/gbk.txt', 'r', encoding='gbk')
f = open('/path/to/gbk.txt', 'r', encoding='gbk', errors='ignore')

6. 写文件

基本写法

  • open(路径, 'w')'wb'文本或二进制。
  • f.write(内容):写入;可反复调用 write()
  • 务必调用 f.close():写文件时 OS 往往先放内存缓存close() 时 OS 才保证把未写入的数据写入磁盘;不 close 可能只写一部分,数据丢失推荐用 with
with open('/path/to/test.txt', 'w') as f:
f.write('Hello, world!')

编码与追加

  • 特定编码的文本:给 open()encoding 参数。
  • 'w'覆盖已存在文件;要追加到末尾用 'a'(append)模式。

小结

要点说明
openopen(路径, 模式);'r' 读、'w' 写、'a' 追加、'rb'/'wb' 二进制
read() 全量;read(size) 按字节;readline() 一行;readlines() 按行 list
write()务必 close()with,否则可能只写一部分
withwith open(...) as f: 自动 close,推荐
编码encoding='gbk' 等;errors='ignore' 忽略编码错误
file-likeread() 即可;StringIO 是内存中的 file-like

记忆:读用 open('r')、写用 open('w');大文件用 read(size) 或 readlines;用 with 保证 close;非 UTF-8 传 encoding。