21·模块六:文件与IO入门

文件读写操作(open, read, write)

file-ioreadwrite

第21课:文件读写操作(open, read, write)

学习目标

通过本课的学习,你将能够:

  1. 掌握使用 open() 函数打开文件,并理解文件模式('r', 'w', 'a')的区别。
  2. 熟练使用 read(), readline(), readlines() 读取文件内容。
  3. 使用 write()writelines() 将数据写入文件。
  4. 理解文件操作后关闭文件的重要性,并了解处理文件操作时可能遇到的常见错误。

核心概念

1. 打开文件:open() 函数

在Python中,操作文件的第一步是打开它。这就像你打开一个记事本准备读写一样。open() 函数就是负责这个工作的。 它的基本形式是:open(文件名, 模式)

  • 文件名:要操作的文件的路径和名称(例如:'data.txt''D:/project/report.csv')。
  • 模式:指定你打开文件想做什么。
    • 'r'读取模式(默认)。文件必须存在,否则会报错。
    • 'w'写入模式。如果文件存在,会清空其内容再写入;如果文件不存在,会创建新文件。
    • 'a'追加模式。如果文件存在,新内容会添加到文件末尾;如果文件不存在,会创建新文件。

2. 读取文件内容

文件打开后,你就可以读取里面的内容了,就像阅读一本书。

  • read():一次性读取文件的全部内容,并返回一个字符串。
  • readline():每次只读取文件的一行,并返回一个字符串。
  • readlines():读取文件的所有行,并返回一个列表,其中每一行是列表的一个元素。

3. 写入文件内容

除了读,你也可以往文件里"写字"。

  • write(字符串):将一个字符串写入文件。注意,它不会自动在字符串末尾添加换行符 \n,你需要手动添加。
  • writelines(字符串列表):将一个字符串列表写入文件,列表中的每个字符串都会被写入,但同样不会自动添加换行符,通常需要在列表元素末尾自行处理换行。

4. 关闭文件:close()

操作完成后,必须关闭文件。这就像用完记事本后要点击关闭一样。关闭文件可以释放系统资源,并确保所有写入的数据都从缓冲区真正保存到磁盘文件中。如果忘记关闭,可能会导致数据丢失或文件被锁住。

代码示例

下面是一个完整的示例,演示了如何创建一个文件、写入内容,然后读取并显示内容。

# 步骤一:以写入模式('w')打开文件,并写入内容
# 注意:使用`with open(...) as file:`语句是更好的做法(下节课详解),这里先用最基础的方式演示。
try:
    # 1. 打开文件
    file = open('my_diary.txt', 'w', encoding='utf-8')
    
    # 2. 写入一些内容
    file.write('2023年10月27日,天气晴朗。\n')  # 手动添加换行符
    file.write('今天我学会了用Python写文件!\n')
    file.write('感觉很有趣,希望明天继续学习。\n')
    
    # 使用 writelines 写入一个列表
    lines = ['第一行列表内容\n', '第二行列表内容\n']
    file.writelines(lines)
    
    # 3. 关闭文件,确保内容保存
    file.close()
    print("文件写入完成!")
except IOError as e:
    print(f"写入文件时发生错误:{e}")

# 步骤二:以读取模式('r')打开同一个文件,读取内容
try:
    file = open('my_diary.txt', 'r', encoding='utf-8')
    
    # 读取整个文件内容
    content = file.read()
    print("== 文件全部内容 (read()) ==")
    print(content)
    
    # 记得关闭后,如果要再次读取,需要重新定位指针或重新打开
    file.seek(0)  # 将文件指针移回文件开头
    
    # 逐行读取
    print("\n== 逐行读取 (readline()) ==")
    line = file.readline()
    while line:  # 当line不为空字符串(即未到文件末尾)时循环
        print(f"读到行: {line.strip()}")  # strip()用于去除末尾的换行符和空白
        line = file.readline()
    
    file.close()
    
    # 重新打开,使用readlines()
    file = open('my_diary.txt', 'r', encoding='utf-8')
    all_lines = file.readlines()
    print(f"\n== 使用readlines()获得的列表 ({len(all_lines)}行) ==")
    for i, line in enumerate(all_lines, 1):
        print(f"{i}: {line.strip()}")
    file.close()
except FileNotFoundError:
    print("错误:找不到要读取的文件。")
except IOError as e:
    print(f"读取文件时发生错误:{e}")

预期输出:

文件写入完成!
== 文件全部内容 (read()) ==
2023年10月27日,天气晴朗。
今天我学会了用Python写文件!
感觉很有趣,希望明天继续学习。
第一行列表内容
第二行列表内容

== 逐行读取 (readline()) ==
读到行: 2023年10月27日,天气晴朗。
读到行: 今天我学会了用Python写文件!
读到行: 感觉很有趣,希望明天继续学习。
读到行: 第一行列表内容
读到行: 第二行列表内容

== 使用readlines()获得的列表 (5行) ==
1: 2023年10月27日,天气晴朗。
2: 今天我学会了用Python写文件!
3: 感觉很有趣,希望明天继续学习。
4: 第一行列表内容
5: 第二行列表内容

实践练习

练习 1:单词统计器(简单)

编写一个程序,打开一个已经存在的文本文件(例如 'sample.txt',你可以先自己创建一个),读取其全部内容,然后统计并打印出单词 "Python" 在文件中出现的次数。

  • 要求:使用 read() 读取。
  • 提示:字符串有 count() 方法。

练习 2:学生信息录入(中等)

创建一个名为 'students.txt' 的文件。

  1. 提示用户输入3个学生的姓名和年龄(例如:"请输入学生1姓名:","请输入学生1年龄:")。
  2. 将每个学生的信息格式化为一行(例如:"姓名:张三,年龄:20")后写入文件,每人一行。
  3. 写入完成后,再次读取该文件,将所有学生信息打印出来。
  • 要求:使用 'w' 模式写入,使用 readlines() 读取。

练习 3:日志合并器(较难)

假设有两个日志文件 'log1.txt''log2.txt',它们内容分别如下(请先创建这两个文件):

  • log1.txt:
    2023-10-01 10:00 系统启动
    2023-10-01 12:30 用户A登录
    
  • log2.txt:
    2023-10-02 09:15 系统更新
    2023-10-02 18:00 用户B登出
    

编写一个程序,将这两个日志文件的内容按时间顺序(这里简单地假设文件本身已按时间排序,且按文件顺序合并即可)合并到一个新文件 'merged_log.txt' 中。

  • 要求:先读取 log1.txt 的所有行,再读取 log2.txt 的所有行,将两个列表合并后写入新文件。

常见错误

  1. 文件模式误用

    • 'w' 模式打开一个已有文件,导致原内容被清空。如果只是想追加内容,应该用 'a' 模式。
    • 'r' 模式打开一个不存在的文件,会引发 FileNotFoundError。在读取前最好用 os.path.exists() 检查。
  2. 忘记关闭文件

    • 这是最常见的问题之一。没有调用 close(),写入的内容可能还在内存缓冲区,没有真正写入磁盘,导致数据"丢失"。这就是为什么下节课我们要学习更安全的 with 语句。
  3. 路径问题

    • 使用相对路径(如 'data.txt')时,程序会在当前工作目录下寻找文件。如果当前目录不是你代码所在的目录,就会找不到文件。可以使用绝对路径或确保当前目录正确。
  4. 编码问题

    • 读写包含中文等非ASCII字符的文件时,务必在 open() 函数中指定 encoding='utf-8'(或其他正确的编码),否则可能出现乱码或报错。

小结

本课我们学习了Python中最基础的文件I/O操作:

  • 打开文件:使用 open(文件名, 模式) 函数,模式决定了操作类型(读、写、追加)。
  • 读取文件read() 读全部,readline() 读一行,readlines() 读所有行到列表。
  • 写入文件write() 写一个字符串,writelines() 写一个字符串列表。
  • 关闭文件:操作完成后务必调用 close() 方法,以保存数据和释放资源。

记住文件操作的"三步曲":打开 -> 操作 -> 关闭。在下一课中,我们将学习 with 语句(上下文管理器),它能自动为我们处理文件的关闭操作,让代码更简洁、更安全。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「上下文管理器(with 语句)」 以巩固所学知识。