1. 文件操作基础:文件概念、文件类型与打开模式详解

说到文件操作,这其实是编程里最基础也最实用的技能之一。我刚开始学Python那会儿,觉得文件读写不就是打开、读写、关闭嘛,有啥好学的?直到有一次做数据处理项目,因为模式选错了,把好不容易爬来的数据全给覆盖了……嗯,从那以后我再也不敢小看这几个模式了。

1.1 文件到底是什么?

说白了,文件就是存储在磁盘上的一段数据。它有个名字,有个路径,还有一堆属性(比如大小、修改时间)。在Python眼里,文件就是一个流——你可以往里面写数据,也可以从里面读数据。

我个人习惯把文件想象成一个盒子:

  • 文本文件:盒子里装的是写好的文字,打开就能看懂
  • 二进制文件:盒子里装的是0和1的编码,需要特定程序才能解读

核心概念:文件操作的三部曲——打开 → 读写 → 关闭。少一步都不行。

1.2 文本文件 vs 二进制文件

这两种文件类型,我经常被新手问到有什么区别。其实很简单:

对比项 文本文件 二进制文件
存储内容 字符(如字母、数字、符号) 原始字节(0和1)
打开方式 记事本就能看 需要对应软件(如图片查看器)
常见类型 .txt, .csv, .json, .html .jpg, .mp3, .exe, .zip
Python模式 'r', 'w', 'a' 等(默认文本模式) 'rb', 'wb', 'ab'(加b后缀)
编码处理 自动处理换行符(\n ↔ \r\n) 不做任何转换

我在项目中遇到过一个问题:用文本模式读取图片文件,结果图片全乱了。原因就是文本模式会自作主张地转换换行符,把二进制数据搞坏了。所以记住:处理非文本文件,一定要用二进制模式。

小技巧:如果你不确定文件类型,可以用 open(file, 'rb') 先读几个字节看看。二进制模式最安全,不会破坏数据。

1.3 文件打开模式详解

这部分是重点,也是坑最多的地方。Python提供了6种基本模式,我一个个说。

1.3.1 'r' 模式(只读)

最常用的模式。文件必须存在,否则报错。只能读,不能写。

# 读取文本文件
with open('notes.txt', 'r', encoding='utf-8') as f:
    content = f.read()
    print(content)

# 读取二进制文件
with open('image.jpg', 'rb') as f:
    data = f.read()

注意:'r'模式下文件不存在会抛出 FileNotFoundError。我曾经在自动化脚本里忘了检查文件是否存在,结果半夜报警……

1.3.2 'w' 模式(只写)

写入模式。如果文件存在,会清空原有内容;如果不存在,会创建新文件。

# 写入文本
with open('output.txt', 'w', encoding='utf-8') as f:
    f.write('这是新内容\n')
    f.write('原有内容会被覆盖')

# 写入二进制
with open('data.bin', 'wb') as f:
    f.write(b'\x00\x01\x02\x03')

避坑指南:我曾经不小心用'w'模式打开了一个重要的配置文件,结果内容全没了。所以用'w'之前,一定确认你真的想覆盖文件。

1.3.3 'a' 模式(追加)

追加模式。文件指针在末尾,写入的内容会追加到文件最后。不会清空原有内容。

# 追加日志
with open('log.txt', 'a', encoding='utf-8') as f:
    f.write(f'[{datetime.now()}] 用户登录成功\n')

我个人特别喜欢用'a'模式写日志文件。每次运行程序,新日志自动追加到末尾,不会丢失历史记录。

1.3.4 'r+' 模式(读写)

可读可写。文件必须存在。写入时从文件开头覆盖,不会清空整个文件。

with open('data.txt', 'r+', encoding='utf-8') as f:
    content = f.read()      # 先读取
    f.write('追加到末尾')   # 写入在末尾(因为读完后指针在末尾)

注意:'r+'模式下,写入的位置取决于当前文件指针的位置。如果你先读了全部内容,指针就在末尾,写入就是追加。如果你seek到开头再写,就会覆盖开头的内容。

1.3.5 'w+' 模式(写读)

可写可读。会清空文件(如果存在)。可以写入后再读取。

with open('temp.txt', 'w+', encoding='utf-8') as f:
    f.write('先写入内容\n')
    f.seek(0)              # 把指针移回开头
    print(f.read())        # 读取刚才写入的内容

嗯,这里要注意:'w+'会清空文件,所以一般用于创建新文件并需要后续读取的场景。

1.3.6 'a+' 模式(追加读)

可追加可读。文件指针在末尾,但可以移动到开头读取内容。

with open('log.txt', 'a+', encoding='utf-8') as f:
    f.write('新日志行\n')
    f.seek(0)              # 移到开头
    all_logs = f.read()    # 读取全部内容

1.4 模式对比速查表

模式 可读 可写 文件必须存在 清空文件 指针位置
'r' ✅ ❌ ✅ ❌ 开头
'w' ❌ ✅ ❌ ✅ 开头
'a' ❌ ✅ ❌ ❌ 末尾
'r+' ✅ ✅ ✅ ❌ 开头
'w+' ✅ ✅ ❌ ✅ 开头
'a+' ✅ ✅ ❌ ❌ 末尾

1.5 知识体系图

下面这张图帮你理清文件操作的核心逻辑:

文件操作知识体系 文件概念 文件类型 打开模式 数据存储单元 有名称和路径 打开→读写→关闭 文本文件 二进制文件 编码处理不同 r / w / a r+ / w+ / a+ 二进制加b后缀 核心原则:选对模式,避免数据丢失 读用r,写用w,追加用a,二进制加b

1.6 实战建议

最后,分享几个我自己的经验:

  1. 用with语句:自动关闭文件,省心又安全。我从来不用裸open()。
  2. 指定编码:文本文件操作时,encoding='utf-8' 是标配。不然在不同系统上可能乱码。
  3. 先测试再覆盖:用'w'模式前,先备份或确认。我吃过亏,你懂的。
  4. 二进制模式不乱用:只有处理图片、音频等非文本文件时才用'b'模式。

一句话总结:文件操作不难,难的是选对模式。记住这张表,你就能避开90%的坑。

可可精品资料库