Python文件操作

一、文件操作的核心概念

  1. 文件路径 :文件在电脑中的位置(如C:\Users\XXX\Desktop\test.txt(Windows)或/Users/XXX/Desktop/test.txt(Mac/Linux))
    • 绝对路径:从根目录开始的完整路径
    • 相对路径:相对于当前程序所在文件夹的路径(如./test.txt表示程序同文件夹下的 test.txt)
  2. 文件模式:打开文件的方式(读、写、追加、二进制等),后面会详细讲
  3. 文件句柄:打开文件后返回的 "操作对象",可以理解为 "文件的遥控器",所有操作都通过它完成
  4. 编码格式 :文件的字符编码(最常用的是utf-8,避免中文乱码)

二、文件操作的基本流程

无论哪种文件操作,核心流程都是:

打开文件(open) → 操作文件(读/写/修改) → 关闭文件(close)

重点:打开的文件必须关闭,否则会占用电脑内存,甚至导致文件损坏!

三、基础操作:打开与关闭文件

3.1 用open()函数打开文件

open()是 Python 内置的打开文件的函数,语法:

python 复制代码
文件句柄 = open(文件路径, 模式, encoding=编码格式)
参数 作用
文件路径 字符串类型,必填;可以是绝对路径或相对路径
模式 字符串类型,可选(默认是r);决定打开文件的方式
encoding 字符串类型,可选;指定文件编码(推荐utf-8,解决中文乱码)
常用文件模式
模式 含义 注意事项
r 只读模式(默认) 文件必须存在,否则报错
w 写入模式 文件不存在则创建,存在则清空原有内容
a 追加模式 文件不存在则创建,新内容追加到文件末尾
r+ 读写模式 文件必须存在,可读可写
w+ 写读模式 清空原有内容,可写可读
a+ 追加 + 读模式 新内容追加到末尾,可读可写
rb 二进制只读模式(如图片、视频、exe 文件) 不指定 encoding,按字节操作
wb 二进制写入模式 同上

3.2 用close()关闭文件

打开文件后,必须用close()关闭,示例:

python 复制代码
# 第一步:打开文件(桌面的test.txt,只读模式,utf-8编码)
# 注意:Windows路径中的\需要转义为\\,或用r前缀(原始字符串)
f = open(r"C:\Users\XXX\Desktop\test.txt", "r", encoding="utf-8")

# (这里可以加读/写操作)

# 第三步:关闭文件
f.close()

3.3 更安全的方式:with语句

手动close()容易忘记,Python 提供了with语句,自动关闭文件,即使代码出错也会关闭,语法:

python 复制代码
with open(文件路径, 模式, encoding=编码格式) as 文件句柄:
    # 缩进内:执行文件操作
    # 缩进结束:自动关闭文件
python 复制代码
# 用with打开文件,自动关闭
with open(r"C:\Users\XXX\Desktop\test.txt", "r", encoding="utf-8") as f:
    # 这里写操作代码
    content = f.read()  # 读取文件内容
    print(content)
# 缩进结束,文件已自动关闭,无需写f.close()

✅ 小白建议:所有文件操作优先用 with 语句,避免忘记关闭文件的坑!

四、文件读取操作

读取文件是获取文件内容的过程,有 4 种常用方法,覆盖所有场景:

4.1 读取全部内容:read()

语法:文件句柄.read(size)

  • size(可选):指定读取的字节数,不写则读取全部
  • 适合小文件(一次性读入内存)
python 复制代码
# 读取整个文件内容
with open("test.txt", "r", encoding="utf-8") as f:  # 相对路径(程序同文件夹)
    all_content = f.read()
    print("文件全部内容:")
    print(all_content)

4.2 按行读取:readline()

语法:文件句柄.readline()

  • 每次读取一行 内容(包括换行符\n
  • 适合大文件(逐行读,节省内存),可配合循环使用
python 复制代码
# 逐行读取文件
with open("test.txt", "r", encoding="utf-8") as f:
    # 读取第一行
    line1 = f.readline()
    print("第一行:", line1)  # 输出带换行符,所以print后会多一空行
    
    # 读取第二行
    line2 = f.readline()
    print("第二行:", line2.strip())  # strip()去掉换行符/空格
    
    # 读取第三行
    line3 = f.readline()
    print("第三行:", line3.strip())
    
    # 读取第四行(无内容,返回空字符串)
    line4 = f.readline()
    print("第四行:", repr(line4))  # repr显示空字符串

输出:

python 复制代码
第一行: Hello Python!

第二行: 我是文件操作的测试内容
第三行: 第3行
第四行: ''

4.3 读取所有行到列表:readlines()

语法:文件句柄.readlines()

  • 将文件的每一行作为列表的一个元素,返回列表
  • 适合需要对每行内容做批量处理的场景
python 复制代码
with open("test.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
    print("所有行的列表:", lines)
    # 遍历列表,处理每行
    for i, line in enumerate(lines):  # enumerate获取行号+内容
        print(f"第{i+1}行:{line.strip()}")

输出:

python 复制代码
所有行的列表: ['Hello Python!\n', '我是文件操作的测试内容\n', '第3行']
第1行: Hello Python!
第2行: 我是文件操作的测试内容
第3行: 第3行

4.4 直接遍历文件句柄(最推荐的逐行读取方式)

语法:for line in 文件句柄:

  • 逐行读取,内存占用最少,适合超大文件(如 10G 的日志文件)
  • 代码最简洁
python 复制代码
# 遍历文件句柄,逐行读取(最优方式)
with open("test.txt", "r", encoding="utf-8") as f:
    for line_num, line in enumerate(f, start=1):  # start=1表示行号从1开始
        print(f"第{line_num}行内容:{line.strip()}")

输出和上面一致,但内存效率更高!

读取的常见问题与解决

  1. 中文乱码 :打开文件时指定encoding="utf-8"

  2. (如果还是乱码,试试gbk,Windows 记事本默认编码是 gbk)

    python 复制代码
    # 解决乱码:切换编码
    with open("test.txt", "r", encoding="gbk") as f:
        print(f.read())
  3. 文件不存在报错FileNotFoundError,检查路径是否正确,或先判断文件是否存在

五、文件写入操作

写入文件是将内容保存到文件的过程,核心模式:w(覆盖)、a(追加)。

5.1 覆盖写入:w模式

⚠️ 重点:w模式会清空文件原有内容,再写入新内容;如果文件不存在,会自动创建。

语法:文件句柄.write(内容)

  • 内容必须是字符串类型(数字需要转成 str)
  • write()返回写入的字符数

示例 1:写入简单内容

python 复制代码
# 覆盖写入(文件不存在则创建)
with open("write_test.txt", "w", encoding="utf-8") as f:
    # 写入字符串
    f.write("这是用w模式写入的内容\n")
    f.write("第二行内容\n")
    # 写入数字(需转字符串)
    f.write(str(123456))

执行后,write_test.txt内容:

python 复制代码
这是用w模式写入的内容
第二行内容
123456

示例 2:多次写入(覆盖原有内容)

python 复制代码
# 第一次写入
with open("write_test.txt", "w", encoding="utf-8") as f:
    f.write("第一次写入的内容")

# 第二次写入(覆盖第一次的内容)
with open("write_test.txt", "w", encoding="utf-8") as f:
    f.write("第二次写入的内容(覆盖了之前的)")

最终文件内容:第二次写入的内容(覆盖了之前的)

5.2 追加写入:a模式

a模式不会清空原有内容,新内容追加到文件末尾;文件不存在则创建。

python 复制代码
# 第一步:先写入初始内容
with open("append_test.txt", "w", encoding="utf-8") as f:
    f.write("初始内容\n")

# 第二步:追加内容(用a模式)
with open("append_test.txt", "a", encoding="utf-8") as f:
    f.write("追加的第一行\n")
    f.write("追加的第二行\n")

# 查看最终内容
with open("append_test.txt", "r", encoding="utf-8") as f:
    print(f.read())

输出:

复制代码
初始内容
追加的第一行
追加的第二行

5.3 写入多行:writelines()

如果有一个字符串列表,想把每个元素作为一行写入,用writelines()

python 复制代码
# 准备要写入的行列表
lines = [
    "第一行\n",  # 手动加换行符,否则会连在一起
    "第二行\n",
    "第三行"
]

with open("lines_test.txt", "w", encoding="utf-8") as f:
    f.writelines(lines)

文件内容:

复制代码
第一行
第二行
第三行

写入的注意事项

  1. 写入的内容必须是字符串 :数字、列表等需用str()转换
  2. 换行需要手动加\n:否则所有内容会写在一行
  3. w模式慎用:确认不需要保留原有内容时再用

六、文件的高级操作

6.1 检查文件 / 文件夹是否存在(避免报错)

os模块(Python 内置)检查路径是否存在,避免FileNotFoundError

python 复制代码
import os  # 导入os模块

# 1. 检查文件是否存在
file_path = "test.txt"
if os.path.exists(file_path):
    print(f"文件{file_path}存在")
else:
    print(f"文件{file_path}不存在")

# 2. 检查是否是文件(避免路径是文件夹)
if os.path.isfile(file_path):
    print(f"{file_path}是文件")

# 3. 检查是否是文件夹
folder_path = "./test_folder"
if os.path.isdir(folder_path):
    print(f"{folder_path}是文件夹")

6.2 文件重命名与删除

os模块实现文件重命名和删除:

python 复制代码
import os

# 1. 重命名文件(旧路径,新路径)
os.rename("old_name.txt", "new_name.txt")

# 2. 删除文件(谨慎使用!删除后无法恢复)
if os.path.exists("delete_me.txt"):  # 先检查是否存在
    os.remove("delete_me.txt")
    print("文件已删除")
else:
    print("文件不存在")

6.3 文件夹操作

python 复制代码
import os

# 1. 创建文件夹
folder_name = "new_folder"
if not os.path.exists(folder_name):
    os.mkdir(folder_name)  # 创建单层文件夹
    # os.makedirs("a/b/c")  # 创建多层文件夹(如a文件夹下的b,b下的c)

# 2. 删除文件夹(空文件夹)
if os.path.exists(folder_name):
    os.rmdir(folder_name)

# 3. 删除非空文件夹(需用shutil模块)
import shutil
shutil.rmtree("non_empty_folder")  # 谨慎使用!

6.4 二进制文件操作(图片 / 视频 / 音频)

操作图片、视频等二进制文件时,用rb/wb模式,不指定 encoding

python 复制代码
# 复制一张图片(二进制读取→二进制写入)
with open("original.jpg", "rb") as f_read:  # 二进制只读
    img_data = f_read.read()  # 读取二进制数据

with open("copy.jpg", "wb") as f_write:  # 二进制写入
    f_write.write(img_data)  # 写入二进制数据
print("图片复制完成")

6.5 文件指针操作(移动读取 / 写入位置)

文件打开后,有一个 "指针"(光标),默认在文件开头,读取 / 写入后指针会移动。用seek()手动移动指针:

python 复制代码
with open("test.txt", "r", encoding="utf-8") as f:
    # 读取前5个字符
    print(f.read(5))  # 输出:Hello
    # 指针现在在第5个字符位置
    # 移动指针到文件开头(0表示开头,2表示末尾)
    f.seek(0)
    # 再次读取全部内容
    print(f.read())  # 输出完整内容

七、实战案例

案例 1:统计文件的行数和字符数

python 复制代码
# 统计test.txt的行数、字符数(排除空格/换行)
file_path = "test.txt"
line_count = 0  # 行数
char_count = 0  # 字符数

with open(file_path, "r", encoding="utf-8") as f:
    for line in f:
        line_count += 1  # 每行计数+1
        # 去掉换行符、空格,统计有效字符
        clean_line = line.strip().replace(" ", "")
        char_count += len(clean_line)

print(f"文件总行数:{line_count}")
print(f"文件有效字符数:{char_count}")

案例 2:批量修改文件内容(替换指定字符串)

python 复制代码
# 将test.txt中的"Python"替换为"Java",保存到新文件
with open("test.txt", "r", encoding="utf-8") as f_read:
    with open("test_new.txt", "w", encoding="utf-8") as f_write:
        for line in f_read:
            # 替换字符串
            new_line = line.replace("Python", "Java")
            # 写入新文件
            f_write.write(new_line)
print("替换完成,新文件已保存")

案例 3:读取大文件(避免内存溢出)

python 复制代码
# 读取10G的超大日志文件,逐行处理(只打印包含"error"的行)
big_file_path = "big_log.txt"
error_count = 0

with open(big_file_path, "r", encoding="utf-8") as f:
    for line in f:  # 逐行读取,内存只存一行
        if "error" in line.lower():  # 忽略大小写
            print(f"错误行:{line.strip()}")
            error_count += 1

print(f"总共找到{error_count}个错误行")

八、常见错误与解决方案

错误类型 原因 解决方案
FileNotFoundError 文件路径错误 / 文件不存在 检查路径拼写;用os.path.exists()先判断
UnicodeDecodeError 编码格式不匹配(如文件是 gbk,用 utf-8 读) 切换 encoding(utf-8/gbk)
PermissionError 没有文件读写权限 / 文件被其他程序占用 关闭占用文件的程序;检查文件权限
IsADirectoryError 路径指向文件夹,却当作文件操作 检查路径是否是文件(os.path.isfile()

总结

  1. 核心流程 :文件操作的基础是打开→操作→关闭,优先用with语句自动关闭文件,避免内存泄漏;
  2. 核心模式 :读取用r,覆盖写入用w,追加写入用a,二进制文件用rb/wb
  3. 核心方法 :读取用read()(小文件)/for line in f(大文件),写入用write(),批量写入用writelines()
  4. 避坑要点 :写入内容必须是字符串,中文乱码指定encoding="utf-8"w模式会覆盖原有内容需慎用。

3.1 读取方法(文本文件)

方法 作用 适用场景
f.read() 一次性读取文件全部内容 小体积文本文件
f.readline() 逐行读取,单次仅读一行 逐行处理、大文件分步读取
f.readlines() 读取所有行,返回字符串列表 需批量处理每行内容
for line in f: 迭代逐行读取,内存占用极低 超大文本文件、日志文件

3.2 写入方法(文本文件)

方法 作用 注意事项
f.write(字符串) 写入单行内容 需手动加换行符\n,仅支持字符串
f.writelines(列表) 批量写入多行内容 列表元素需为字符串,换行需手动添加

3.3 文件/文件夹管理(os模块常用操作)

操作类型 核心语法 备注
判断路径是否存在 os.path.exists(路径) 判断文件/文件夹,返回布尔值
判断是否为文件 os.path.isfile(路径) 区分文件与文件夹
文件重命名 os.rename(旧名, 新名) 需保证原文件存在
删除文件 os.remove(文件路径) 删除后无法恢复,谨慎使用
创建文件夹 os.mkdir(文件夹名) os.makedirs(路径) 创建单层目录 可一次性创建多级目录,无需逐层级创建
删除空文件夹 os.rmdir(文件夹名) 仅支持删除空目录
相关推荐
卷无止境6 分钟前
终端里的AI辅助,一场正在发生的编程效率变革
后端·python
苏灿烤鱼7 分钟前
上下文写成文件系统,为什么向量还能静默丢?
python·github·agent
caimouse8 分钟前
ReactOS 图形系统分析(48):弧线绘制 — arc.c
c语言·开发语言
SamChan901 小时前
对比 4 种主流 PDF 文档解析方案:PyMuPDF vs pdfplumber vs Apache PDFBox vs 大模型 OCR
python·ai·pdf·ocr·apache·机器翻译
cypking1 小时前
Objective-C 语法完整学习手册(小白自学 + 开发备查)
c语言·开发语言·学习·objective-c
ambition202423 小时前
操作系统同步:读者-写者问题与读写公平法详解(附每个 PV 操作含义)
linux·开发语言·数据结构·unix
chuan.bai6 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
离陌在学C#8 小时前
C# 事件(Event)详解:从概念到实战
开发语言·c#
Terra.K8 小时前
Java异常学习[特殊字符]
java·开发语言·学习
安_9 小时前
如何构建和使用向量索引?HNSW 和 IVF 有什么区别?
python·ai