第7章:Python 文件操作
7.1 文件的打开和关闭
在 Python 中,使用 open() 函数来打开文件,使用 close() 方法来关闭文件。
基本语法
# 打开文件
file = open(filename, mode)
# 操作文件
...
# 关闭文件
file.close()
文件打开模式
| 模式 | 描述 |
|---|---|
'r' | 只读模式(默认) |
'w' | 写入模式,会覆盖已有文件 |
'a' | 追加模式,在文件末尾添加内容 |
'x' | 独占创建模式,文件已存在则报错 |
'b' | 二进制模式 |
't' | 文本模式(默认) |
'+' | 读写模式 |
使用 with 语句(推荐)
with 语句会自动处理文件的关闭,即使发生异常也能保证文件被正确关闭。
with open('example.txt', 'r') as file:
# 操作文件
content = file.read()
print(content)
# 退出 with 块后,文件自动关闭
7.2 读取文件
读取整个文件
# 读取整个文件
with open('example.txt', 'r') as file:
content = file.read()
print(content)
逐行读取
# 逐行读取(方法1)
with open('example.txt', 'r') as file:
for line in file:
print(line.strip()) # strip() 移除换行符
# 逐行读取(方法2)
with open('example.txt', 'r') as file:
lines = file.readlines()
for line in lines:
print(line.strip())
# 逐行读取(方法3)
with open('example.txt', 'r') as file:
line = file.readline()
while line:
print(line.strip())
line = file.readline()
读取指定字节数
# 读取指定字节数
with open('example.txt', 'r') as file:
content = file.read(100) # 读取前 100 个字符
print(content)
7.3 写入文件
写入文件
# 写入文件(覆盖模式)
with open('example.txt', 'w') as file:
file.write('Hello, World!\n')
file.write('This is a test.\n')
# 追加文件
with open('example.txt', 'a') as file:
file.write('Adding more content.\n')
# 写入多行
lines = ['Line 1\n', 'Line 2\n', 'Line 3\n']
with open('example.txt', 'w') as file:
file.writelines(lines)
二进制文件操作
# 写入二进制文件
with open('image.jpg', 'rb') as file:
content = file.read()
with open('copy.jpg', 'wb') as file:
file.write(content)
7.4 文件指针操作
文件指针指向文件中的当前位置,用于读写操作。
获取文件指针位置
with open('example.txt', 'r') as file:
print(f"Initial position: {file.tell()}")
content = file.read(10)
print(f"After reading 10 characters: {file.tell()}")
移动文件指针
with open('example.txt', 'r') as file:
# 移动到文件开头
file.seek(0)
print(f"Position after seek(0): {file.tell()}")
# 移动到文件末尾
file.seek(0, 2) # 2 表示相对于文件末尾
print(f"Position at end: {file.tell()}")
# 移动到文件中间
file.seek(10) # 移动到第 10 个字节
print(f"Position at 10: {file.tell()}")
模式说明
seek(offset, whence):offset: 偏移量whence: 参考位置- 0: 文件开头(默认)
- 1: 当前位置
- 2: 文件末尾
7.5 异常处理
文件操作可能会遇到各种异常,如文件不存在、权限不足等,需要使用异常处理来处理这些情况。
基本异常处理
try:
with open('non_existent.txt', 'r') as file:
content = file.read()
print(content)
except FileNotFoundError:
print("File not found!")
except PermissionError:
print("Permission denied!")
except Exception as e:
print(f"Error: {e}")
综合异常处理
def read_file(filename):
"""读取文件内容"""
try:
with open(filename, 'r') as file:
content = file.read()
return content
except FileNotFoundError:
print(f"Error: File '{filename}' not found")
return None
except PermissionError:
print(f"Error: Permission denied for '{filename}'")
return None
except Exception as e:
print(f"Error: {e}")
return None
# 测试
content = read_file('example.txt')
if content:
print(content)
7.6 文件和目录操作
Python 的 os 和 os.path 模块提供了文件和目录操作的功能。
导入模块
import os
import os.path
检查文件和目录
# 检查文件是否存在
print(os.path.exists('example.txt'))
# 检查是否是文件
print(os.path.isfile('example.txt'))
# 检查是否是目录
print(os.path.isdir('docs'))
# 获取文件大小
print(os.path.getsize('example.txt'))
# 获取文件修改时间
import time
mod_time = os.path.getmtime('example.txt')
print(time.ctime(mod_time))
目录操作
# 创建目录
os.makedirs('new_dir', exist_ok=True) # exist_ok=True 表示目录已存在也不报错
# 列出目录内容
print(os.listdir('.'))
# 更改当前目录
os.chdir('new_dir')
print(os.getcwd()) # 获取当前目录
os.chdir('..') # 返回上一级目录
# 删除目录
os.rmdir('new_dir') # 只能删除空目录
文件操作
# 重命名文件
os.rename('old.txt', 'new.txt')
# 删除文件
os.remove('example.txt')
# 复制文件
import shutil
shutil.copy('source.txt', 'destination.txt')
# 移动文件
shutil.move('source.txt', 'destination.txt')
7.7 综合示例
示例1:文件复制
def copy_file(source, destination):
"""复制文件"""
try:
with open(source, 'rb') as src_file:
content = src_file.read()
with open(destination, 'wb') as dest_file:
dest_file.write(content)
print(f"File copied from {source} to {destination}")
return True
except Exception as e:
print(f"Error copying file: {e}")
return False
# 测试
copy_file('example.txt', 'example_copy.txt')
示例2:文件统计
def file_statistics(filename):
"""统计文件信息"""
try:
with open(filename, 'r') as file:
content = file.read()
# 统计行数
lines = content.count('\n') + 1
# 统计单词数
words = len(content.split())
# 统计字符数
characters = len(content)
# 统计空白字符数
spaces = content.count(' ')
print(f"File: {filename}")
print(f"Lines: {lines}")
print(f"Words: {words}")
print(f"Characters: {characters}")
print(f"Spaces: {spaces}")
except Exception as e:
print(f"Error: {e}")
# 测试
file_statistics('example.txt')
示例3:日志记录
def log_message(message, log_file='app.log'):
"""记录日志"""
import datetime
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_entry = f"[{timestamp}] {message}\n"
try:
with open(log_file, 'a') as file:
file.write(log_entry)
print(f"Logged: {message}")
except Exception as e:
print(f"Error logging message: {e}")
# 测试
log_message('Application started')
log_message('User logged in: admin')
log_message('Error: Database connection failed')
示例4:CSV 文件处理
import csv
# 写入 CSV 文件
def write_csv(filename, data):
"""写入 CSV 文件"""
try:
with open(filename, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Name', 'Age', 'City'])
writer.writerows(data)
print(f"CSV file written: {filename}")
except Exception as e:
print(f"Error writing CSV: {e}")
# 读取 CSV 文件
def read_csv(filename):
"""读取 CSV 文件"""
try:
with open(filename, 'r') as file:
reader = csv.reader(file)
for row in reader:
print(row)
except Exception as e:
print(f"Error reading CSV: {e}")
# 测试
data = [
['John', 30, 'New York'],
['Alice', 25, 'London'],
['Bob', 35, 'Paris']
]
write_csv('users.csv', data)
print("\nReading CSV file:")
read_csv('users.csv')
7.8 常见问题和解决方案
问题1:文件路径问题
# 绝对路径 vs 相对路径
# 绝对路径
absolute_path = 'C:\\Users\\username\\example.txt' # Windows
absolute_path = '/home/username/example.txt' # Linux/macOS
# 相对路径
relative_path = 'example.txt' # 当前目录
relative_path = 'data/example.txt' # 子目录
relative_path = '../example.txt' # 父目录
# 使用 os.path 构建路径
import os
path = os.path.join('data', 'files', 'example.txt')
print(path) # 会根据操作系统自动使用正确的路径分隔符
问题2:编码问题
# 指定编码
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
# 处理编码错误
with open('example.txt', 'r', encoding='utf-8', errors='replace') as file:
content = file.read()
问题3:大文件处理
# 处理大文件(逐行读取)
def process_large_file(filename):
"""处理大文件"""
try:
with open(filename, 'r') as file:
for line in file:
# 处理每一行
print(line.strip())
except Exception as e:
print(f"Error: {e}")
# 测试
process_large_file('large_file.txt')
7.9 练习
- 文件读取练习:编写一个程序,读取一个文本文件,并统计其中的行数、单词数和字符数
- 文件写入练习:编写一个程序,将用户输入的内容保存到文件中
- 文件复制练习:编写一个程序,复制一个文件到另一个位置
- 文件搜索练习:编写一个程序,在指定目录中搜索包含特定关键词的文件
- CSV 处理练习:编写一个程序,读取一个 CSV 文件,计算平均值,然后将结果写入新的 CSV 文件
- 日志分析练习:编写一个程序,分析日志文件,统计错误出现的次数
7.10 小结
本章我们学习了:
- 文件的打开和关闭
- 读取文件的不同方式
- 写入文件的不同方式
- 文件指针操作
- 异常处理
- 文件和目录操作
- 综合示例
现在你已经掌握了 Python 的文件操作,可以开始学习 Python 的异常处理了!