摘要:本文系统介绍了 Python 中文件与目录操作的核心知识。首先阐述了 IO 流的基本概念,然后详细讲解了文件流的读写操作(包括读、写、'+'模式)以及 with 语句的用法。最后,全面列举了文件与文件夹操作的常用方法,涵盖 os、os.path、shutil、pathlib 等模块,并提供了遍历目录和文件的实用技巧。文章旨在帮助读者掌握 Python 文件处理的核心技能,提升开发效率。
目录
1. Python IO 流基础
2. 文件流操作详解
2.1 读文件操作
2.2 写文件操作
2.3 '+' 模式的使用
3. With 语句的用法
4. 文件与文件夹操作常用方法
4.1 os 模块常用方法
4.2 os.path 模块常用方法
4.3 shutil 模块常用方法
4.4 pathlib 模块(Python 3.4+ 推荐)
4.5 遍历目录和文件
总结
1. Python IO 流基础
在 Python 中,IO(Input/Output,输入/输出)流是数据在程序和外部世界(如文件、网络、控制台)之间流动的抽象概念。Python 通过内置的io模块提供了丰富的流处理工具,但最常用的是文件流。
通过“流”的形式允许计算机程序使用相同的方式来访问不同的输入/输出源。stream是从起源(source)到接收的(sink)的有序数据。我们这里把输入/输出源对比成“水桶”,那么流就是“管道”。
文件流的核心是open()函数,它返回一个文件对象(也称为文件句柄),通过这个对象我们可以对文件进行读写操作。
2. 文件流操作详解
2.1 读文件操作
- 打开文件流
- 语法f = open(file, mode='r', [encoding=None, ...])
- open函数最常用的三个参数如下:
- file:要操作的文件路径
- mode:文件的打开模式
- r :读取(默认值)
- w :写入,并先截断文件
- x :排它性创建,如果文件已存在,则创建失败
- a :打开文件用于写入,如果文件存在,则在文件末尾追加内容
- b :二进制模式
- t :文本模式(默认值)
- + :打开用于更新(读取与写入)
- encoding:字符编码
- 读操作
- 文件对象.read() : 默认读取整个文件。 或者可以读取指定大小的数据
- 若不传递size参数,表示:读取文件中所有的内容(注意内存占用!)。
- 若传递了size参数,表示:读取文件中指定个数的字符,或指定大小的字节。
- 文件对象.readlines()
- 文件对象.readline()
- 文件对象.read() : 默认读取整个文件。 或者可以读取指定大小的数据
Python 提供了多种读取文件内容的方法:
# 1. 读取整个文件内容 with open('example.txt', 'r', encoding='utf-8') as f: content = f.read() # 读取全部内容 print(content) 2. 逐行读取 with open('example.txt', 'r', encoding='utf-8') as f: for line in f: # 文件对象是可迭代的 print(line.strip()) # strip() 去除行尾换行符 3. 读取指定字节数 with open('example.txt', 'r', encoding='utf-8') as f: chunk = f.read(100) # 读取前100个字符 print(chunk) 4. 读取所有行到列表 with open('example.txt', 'r', encoding='utf-8') as f: lines = f.readlines() # 返回包含所有行的列表 for line in lines: print(line.strip())下面会单独介绍with语句,如果不用with语句,需要手动关闭资源。
f = open(file='D:\\text.txt', mode='rt', encoding='utf-8') f.close()2.2 写文件操作
- 打开文件流
- 语法f = open(file, mode='wt', [encoding=None, ...])
- 注意:如果文件不存在,会创建该文件
- mode:文件的打开模式
- `w` :写入,先清空源文件内容,再写入
- `x` :排它性创建,如果文件已存在,则创建失败
- a` :打开文件用于写入,如果文件存在,则在文件末尾追加内容
- 写操作
- 文件对象.write()
- 文件对象.flush():Python 写入文件时,并不是每写一次就立刻落盘,而是:先写到“缓冲区”里。flush方法:把缓冲区中的数据,立刻写入到文件中。(或者close方法执行的时候也会把缓冲区内容写入文件的)
写入文件时需要注意打开模式:
# 1. 覆盖写入('w' 模式) with open('output.txt', 'w', encoding='utf-8') as f: f.write('Hello, World!\n') # 写入字符串 f.writelines(['Line 1\n', 'Line 2\n']) # 写入多行 2. 追加写入('a' 模式) with open('log.txt', 'a', encoding='utf-8') as f: f.write(f'{datetime.now()}: User logged in\n') 注意:'w' 模式会清空文件原有内容,'a' 模式则在文件末尾追加2.3 '+' 模式的使用
open函数最常用的三个参数如下:
- file:要操作的文件路径
- mode:文件的打开模式
- r` :读取(默认值)
- `w` :写入,并先截断文件
- x` :排它性创建,如果文件已存在,则创建失败
- `a` :打开文件用于写入,如果文件存在,则在文件末尾追加内容
- `b` :二进制模式
- `t` :文本模式(默认值)
- `+` :打开用于更新(读取与写入)
- encoding:字符编码
其中:
+ 的作用就是给“单一功能”的模式增加“另一半”的能力。
不带 + 的模式(单一职责)
- 'r'(只读):只能读,不能写。写就报错。
- 'w'(只写):只能写,不能读。读就报错。
- 'a'(只追加):只能写(且只能写在末尾),不能读。
带上 +的模式(读写二合一)
- 'r+':读 + 写(但文件必须存在,且不会清空原内容)。
- 'w+':写 + 读(文件不存在就创建,存在就清空原内容)。
'a+':追加 + 读(文件不存在就创建,不清空,指针在末尾)。
'+' 模式表示同时支持读写操作:
# 'r+' 模式:读写模式,文件必须存在 with open('data.txt', 'r+', encoding='utf-8') as f: content = f.read() # 先读取 f.seek(0) # 移动文件指针到开头 f.write('Updated: ' + content) # 写入修改 'w+' 模式:读写模式,会创建新文件或清空已有文件 with open('temp.txt', 'w+', encoding='utf-8') as f: f.write('Initial content\n') f.seek(0) # 回到开头读取 print(f.read()) 'a+' 模式:追加读写模式 with open('log.txt', 'a+', encoding='utf-8') as f: f.write('New log entry\n') f.seek(0) # 可以读取,但写入总是在末尾 print(f.read())3. With 语句的用法
with语句是 Python 的上下文管理器,用于自动管理资源(如文件关闭、数据库连接断开、锁释放等)的打开和关闭:
# 传统方式需要手动关闭文件 f = open('file.txt', 'r') try: content = f.read() finally: f.close() # 必须手动关闭 使用 with 语句(推荐) with open('file.txt', 'r') as f: content = f.read() 离开 with 块后,文件会自动关闭,即使发生异常也会关闭 同时打开多个文件 with open('input.txt', 'r') as fin, open('output.txt', 'w') as fout: content = fin.read() fout.write(content.upper())优点:
- 自动管理资源,确保文件正确关闭
- 代码更简洁,可读性更好
- 异常安全,即使出现异常也能保证资源释放
with语句后跟的上下文是一个对象,对象中需要有enter方法和exit方法。
4. 文件与文件夹操作常用方法
4.1 os 模块常用方法
import os # ========== 系统信息 ========== os.name # 【系统信息】查看当前操作系统名字,"nt"表示Windows,"posix"表示Linux os.sep # 【系统信息】获取当前系统平台路径分隔符 # ========== 目录操作 ========== os.getcwd() # 【目录操作】获取当前工作目录 os.listdir(path) # 【目录操作】列出指定目录path的所有文件和目录名 os.chdir(path) # 【目录操作】切换当前工作目录 os.mkdir(path) # 【目录操作】创建单层目录(父目录必须存在) os.makedirs(path) # 【目录操作】创建多层目录(自动创建不存在的父目录) os.rmdir(path) # 【目录操作】删除单层空目录(目录必须为空) os.removedirs(path) # 【目录操作】递归删除多层空目录(从最内层开始),递归删除多层空目录,从最内层往外层删,中途任意目录非空则终止报错;仅能删空目录 os.path.isdir(path) # 【目录操作】判断指定路径目标是否为目录 os.path.dirname(path) # 【目录操作】提取路径中的目录部分 ========== 文件操作 ========== os.remove(file_name) # 【文件操作】删除指定文件(不能删除目录) os.rename(old_name, new_name) # 【文件/目录操作】重命名文件或目录 os.path.isfile(path) # 【文件操作】判断指定路径目标是否为文件 os.path.splitext(path) # 【文件操作】分离文件扩展名,返回 (文件名, 扩展名) os.path.basename(path) # 【文件操作】提取文件名(含扩展名) os.path.getsize(path) # 【文件操作】返回文件大小(字节) ========== 路径操作(通用) ========== os.path.abspath(path) # 【路径操作】获取指定相对路径的绝对路径(文件或目录均可) os.path.split(path) # 【路径操作】分割路径为 (目录, 文件名) 元组 os.path.exists(path) # 【路径操作】判断指定路径是否存在(文件或目录均可) os.path.join(path, *paths) # 【路径操作】连接多个路径片段,自动添加正确分隔符 ========== 环境变量 ========== os.environ[key] # 【环境变量】获取当前环境变量值(不存在报错 KeyError),字典取值,key不存在直接抛KeyError;可写os.environ.get(key)等价os.getenv os.getenv(key) # 【环境变量】获取当前环境变量值(不存在返回 None)import os 文件和目录操作 os.rename('old.txt', 'new.txt') # 重命名文件 os.remove('file.txt') # 删除文件 os.mkdir('new_dir') # 创建目录 os.makedirs('path/to/deep/dir', exist_ok=True) # 创建多级目录 os.rmdir('empty_dir') # 删除空目录 os.removedirs('a/b/c') # 递归删除空目录 路径操作 current_dir = os.getcwd() # 获取当前工作目录 os.chdir('/path/to/dir') # 改变当前目录 abs_path = os.path.abspath('file.txt') # 获取绝对路径 base_name = os.path.basename('/path/to/file.txt') # 获取文件名 dir_name = os.path.dirname('/path/to/file.txt') # 获取目录名 判断文件类型 os.path.exists('file.txt') # 路径是否存在 os.path.isfile('file.txt') # 是否是文件 os.path.isdir('dir') # 是否是目录 os.path.getsize('file.txt') # 获取文件大小(字节)4.2 os.path 模块常用方法
import os.path 路径拼接和分割 full_path = os.path.join('dir', 'subdir', 'file.txt') # 智能拼接路径 path_parts = os.path.split('/path/to/file.txt') # 分割为目录和文件名 name_ext = os.path.splitext('document.pdf') # 分割文件名和扩展名 路径信息获取 file_size = os.path.getsize('data.txt') # 文件大小 mod_time = os.path.getmtime('file.txt') # 最后修改时间 access_time = os.path.getatime('file.txt') # 最后访问时间 create_time = os.path.getctime('file.txt') # 创建时间(Unix 系统)4.3 shutil 模块常用方法
import shutil 文件操作 shutil.copy('source.txt', 'dest.txt') # 复制文件 shutil.copy2('source.txt', 'dest.txt') # 复制文件并保留元数据 shutil.move('old.txt', 'new.txt') # 移动/重命名文件 目录操作 shutil.copytree('src_dir', 'dst_dir') # 递归复制目录 shutil.rmtree('dir_to_delete') # 递归删除目录(包括非空目录) 磁盘使用 total, used, free = shutil.disk_usage('/') # 获取磁盘使用情况4.4 pathlib 模块(Python 3.4+ 推荐)
from pathlib import Path 创建 Path 对象 p = Path('example.txt') 文件操作 p.write_text('Hello, World!') # 写入文本 content = p.read_text() # 读取文本 p.rename('new_name.txt') # 重命名 p.unlink() # 删除文件 目录操作 dir_path = Path('my_dir') dir_path.mkdir(exist_ok=True) # 创建目录 for file in dir_path.iterdir(): # 遍历目录 print(file.name) 路径操作 parent = p.parent # 父目录 name = p.name # 文件名 stem = p.stem # 文件名(不含扩展名) suffix = p.suffix # 扩展名 absolute = p.absolute() # 绝对路径4.5 遍历目录和文件
import os 遍历当前目录所有文件和子目录 for root, dirs, files in os.walk('.'): print(f'当前目录: {root}') print(f'子目录: {dirs}') print(f'文件: {files}') print('---') 列出目录内容 files = os.listdir('.') # 返回名称列表 entries = os.scandir('.') # 返回 DirEntry 对象(性能更好) for entry in entries: if entry.is_file(): print(f'文件: {entry.name}, 大小: {entry.stat().st_size}字节') elif entry.is_dir(): print(f'目录: {entry.name}')总结
Python 提供了丰富的文件与目录操作工具:
- 文件读写:使用
open()函数配合不同模式('r', 'w', 'a', '+') - 资源管理:推荐使用
with语句自动管理文件关闭 - 路径操作:
os.path用于传统路径处理,pathlib提供更现代的面向对象接口 - 文件操作:
os模块提供基础操作,shutil提供高级文件操作 - 目录遍历:
os.walk()和os.scandir()用于递归遍历目录
在实际开发中,建议优先使用pathlib(Python 3.4+)和with语句,它们能让代码更简洁、安全。