Python文件读写方法
Python文件读写是编程中非常基础且重要的技能,无论是处理数据、保存程序状态还是读取配置信息,都离不开文件操作。本教程将全面介绍Python中文件读写的方法,涵盖基本操作、高级技巧、常见问题及解决方案,帮助您掌握这一核心技能。
1. 文件基础概念
在Python中,文件被视为一个连续的字节序列,每个文件都有一个文件名和路径。文件操作主要涉及三个基本步骤:打开文件、读写文件和关闭文件。Python使用内置的open()函数来处理文件,该函数返回一个文件对象,通过该对象可以对文件进行读写操作。
文件路径分为绝对路径和相对路径。绝对路径是从根目录开始的完整路径,如C:\Users\username\file.txt;相对路径是相对于当前工作目录的路径,如data/file.txt。在Windows系统中,路径分隔符使用反斜杠\,但在Python字符串中反斜杠是转义字符,因此通常使用双反斜杠\\或原始字符串r'path\to\file'。跨平台更推荐使用正斜杠/,因为Python会自动处理路径分隔符。
文件打开模式决定了文件如何被访问:
'r':只读模式(默认)
'w':写入模式(会覆盖已有文件)
'a':追加模式(在文件末尾添加内容)
'x':独占创建模式(文件必须不存在)
'b':二进制模式
't':文本模式(默认)
'+':读写模式
这些模式可以组合使用,如'rb'表示二进制读取模式,'w+'表示读写模式(会覆盖文件)。
2. 打开和关闭文件
打开文件使用open()函数,基本语法为:
file_object = open(file_path, mode='r', encoding=None)
参数说明:
file_path:文件路径(字符串)
mode:打开模式(字符串)
encoding:文件编码(如'utf-8'),文本模式必需
关闭文件使用文件对象的close()方法:
file_object.close()
示例代码:
# 打开文件
file = open('example.txt', 'r', encoding='utf-8')
# 在这里进行文件操作...
# 关闭文件
file.close()
重要说明:必须确保文件被正确关闭,否则可能导致资源泄露或数据损坏。更安全的方法是使用with语句(上下文管理器),它会在代码块结束时自动关闭文件,即使在操作过程中发生异常。
with open('example.txt', 'r', encoding='utf-8') as file:
# 文件操作
content = file.read()
print(content)
# 文件已自动关闭
3. 读取文本文件
3.1. 读取整个文件
使用read()方法读取整个文件内容为一个字符串:
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
print(content)
注意事项:对于大文件,一次性读取全部内容可能会消耗大量内存,此时应考虑逐行读取或分块读取。
3.2. 逐行读取
使用readline()方法读取单行内容:
with open('example.txt', 'r', encoding='utf-8') as file:
line = file.readline()
while line:
print(line.strip()) # 去除行尾换行符
line = file.readline()
或者使用readlines()方法读取所有行到一个列表:
with open('example.txt', 'r', encoding='utf-8') as file:
lines = file.readlines()
for line in lines:
print(line.strip())
更Pythonic的方式:直接迭代文件对象,逐行读取,内存效率高:
with open('example.txt', 'r', encoding='utf-8') as file:
for line in file:
print(line.strip())
3.3. 按固定大小读取
使用read(size)方法按指定大小读取(单位为字节):
with open('example.txt', 'r', encoding='utf-8') as file:
chunk_size = 100 # 每次读取100个字符
while True:
chunk = file.read(chunk_size)
if not chunk: # 到达文件末尾
break
print(chunk, end='')
4. 写入文本文件
4.1. 写入字符串
使用write()方法写入字符串,返回写入的字符数:
with open('output.txt', 'w', encoding='utf-8') as file:
file.write('Hello, World!\n')
file.write('This is a test file.\n')
注意事项:write()方法不会自动添加换行符,需要手动添加\n。
4.2. 写入多行
使用writelines()方法写入字符串列表,但不会自动添加换行符:
lines = ['First line\n', 'Second line\n', 'Third line\n']
with open('output.txt', 'w', encoding='utf-8') as file:
file.writelines(lines)
4.3. 追加内容
使用追加模式'a'在文件末尾添加内容:
with open('output.txt', 'a', encoding='utf-8') as file:
file.write('This line will be appended.\n')
5. 二进制文件操作
对于非文本文件(如图片、音频、视频),需要使用二进制模式(添加'b'):
# 读取二进制文件
with open('image.jpg', 'rb') as file:
binary_data = file.read()
print(len(binary_data), 'bytes read')
# 写入二进制文件
with open('copy.jpg', 'wb') as file:
file.write(binary_data)
二进制模式下不能使用encoding参数,因为数据是原始字节流。
6. 文件指针操作
文件指针表示当前读写位置,Python提供两个方法控制指针位置:
tell():返回当前指针位置(从文件开头算起的字节数)
seek(offset, whence):移动指针位置
offset:偏移量(字节数)
whence:参考位置(0:文件开头,1:当前位置,2:文件末尾)
示例代码:
with open('example.txt', 'r+b') as file: # 读写二进制模式
file.write(b'0123456789') # 写入10个字节
print(file.tell()) # 输出当前指针位置:10
file.seek(0) # 移动到文件开头
data = file.read(3) # 读取3个字节:b'012'
print(data)
file.seek(2, 1) # 从当前位置移动2个字节(位置从3到5)
print(file.read(3)) # 读取位置5-7:b'567'
file.seek(-5, 2) # 从文件末尾移动5个字节(位置5)
print(file.read()) # 读取位置5到末尾:b'56789'
注意事项:
文本模式下,seek()只能相对于文件开头移动(whence只能是0)
非ASCII字符在文本模式下可能占用多个字节,指针位置可能不准确
7. 文件与目录操作
Python的os模块提供了丰富的文件和目录操作功能:
7.1. 基本路径操作
import os
# 获取当前工作目录
current_dir = os.getcwd()
print('Current directory:', current_dir)
# 改变工作目录
os.chdir('/path/to/directory')
# 创建目录
os.mkdir('new_folder') # 创建单层目录
os.makedirs('parent/child', exist_ok=True) # 创建多层目录
# 列出目录内容
entries = os.listdir('.')
print('Entries:', entries)
# 检查路径是否存在
print('File exists:', os.path.exists('example.txt'))
# 检查是否是文件或目录
print('Is file:', os.path.isfile('example.txt'))
print('Is directory:', os.path.isdir('example.txt'))
7.2. 路径拼接与分割
# 拼接路径(跨平台)
file_path = os.path.join('data', 'files', 'example.txt')
print('Joined path:', file_path)
# 分割路径
dirname, filename = os.path.split(file_path)
print('Directory:', dirname)
print('Filename:', filename)
# 获取绝对路径
abs_path = os.path.abspath(file_path)
print('Absolute path:', abs_path)
# 获取文件名和扩展名
filename, ext = os.path.splitext(file_path)
print('Filename without extension:', filename)
print('Extension:', ext)
7.3. 文件管理操作
# 重命名文件或目录
os.rename('old_name.txt', 'new_name.txt')
# 删除文件
os.remove('unwanted_file.txt')
# 删除空目录
os.rmdir('empty_folder')
# 删除目录及其内容(谨慎使用)
import shutil
shutil.rmtree('non_empty_folder')
# 复制文件
shutil.copy('source.txt', 'destination.txt')
# 移动文件(相当于重命名)
shutil.move('source.txt', 'destination.txt')
8. 常见格式文件处理
8.1. CSV文件处理
使用内置的csv模块处理CSV文件:
import csv
# 写入CSV文件
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerow(['Name', 'Age', 'City'])
writer.writerow(['Alice', 25, 'New York'])
writer.writerow(['Bob', 30, 'Los Angeles'])
# 读取CSV文件
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
print(', '.join(row))
使用DictReader和DictWriter处理带表头的CSV:
# 写入带表头的CSV
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
fieldnames = ['Name', 'Age', 'City']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'Name': 'Alice', 'Age': 25, 'City': 'New York'})
writer.writerow({'Name': 'Bob', 'Age': 30, 'City': 'Los Angeles'})
# 读取带表头的CSV
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
print(row['Name'], row['Age'], row['City'])
8.2. JSON文件处理
使用内置的json模块处理JSON文件:
import json
# 写入JSON文件
data = {
'name': 'John Doe',
'age': 35,
'is_student': False,
'courses': ['Math', 'Physics', 'Chemistry']
}
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(data, file, indent=4) # indent=4美化输出
# 读取JSON文件
with open('data.json', 'r', encoding='utf-8') as file:
loaded_data = json.load(file)
print(loaded_data)
print('Name:', loaded_data['name'])
print('First course:', loaded_data['courses'][0])
处理JSON字符串:
# 将Python对象转换为JSON字符串
json_str = json.dumps(data, indent=4)
print(json_str)
# 将JSON字符串解析为Python对象
parsed_data = json.loads(json_str)
print(parsed_data)
9. 错误处理与异常捕获
文件操作中常见的异常包括:
FileNotFoundError:文件或目录不存在
PermissionError:权限不足
IsADirectoryError:对目录进行了文件操作
NotADirectoryError:对文件进行了目录操作
FileExistsError:文件已存在(在独占创建模式下)
OSError:操作系统相关错误
使用try...except捕获异常:
try:
with open('nonexistent_file.txt', 'r', encoding='utf-8') as file:
content = file.read()
except FileNotFoundError:
print('Error: File not found!')
except PermissionError:
print('Error: Permission denied!')
except OSError as e:
print(f'Error: {e}')
else:
print('File read successfully')
print(content)
更健壮的文件操作函数:
def read_file_safely(file_path):
try:
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
except FileNotFoundError:
print(f"Error: File '{file_path}' not found!")
except PermissionError:
print(f"Error: No permission to read '{file_path}'!")
except OSError as e:
print(f"Error reading file '{file_path}': {e}")
return None
content = read_file_safely('example.txt')
if content is not None:
print(content)
10. 高级文件操作
10.1. 内存映射文件
对于大文件,可以使用mmap模块创建内存映射文件,实现高效访问:
import mmap
with open('large_file.bin', 'r+b') as file:
# 创建内存映射
with mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# 读取前100个字节
data = mm.read(100)
print(data)
# 查找字节序列
pos = mm.find(b'pattern')
if pos != -1:
print(f"Pattern found at position {pos}")
10.2. 临时文件处理
使用tempfile模块创建临时文件:
import tempfile
# 创建临时文件
with tempfile.NamedTemporaryFile(mode='w+', delete=False) as temp_file:
temp_file.write('Temporary data\n')
temp_file.write('Will be deleted after context\n')
temp_path = temp_file.name # 获取临时文件路径
# 临时文件仍然存在(因为delete=False)
print(f"Temporary file created at: {temp_path}")
# 再次读取临时文件
with open(temp_path, 'r') as file:
print(file.read())
# 手动删除临时文件
import os
os.unlink(temp_path)
10.3. 文件压缩
使用gzip模块处理压缩文件:
import gzip
# 写入压缩文件
with gzip.open('compressed.gz', 'wt', encoding='utf-8') as file:
file.write('This text will be compressed\n')
file.write('Compressed with gzip\n')
# 读取压缩文件
with gzip.open('compressed.gz', 'rt', encoding='utf-8') as file:
print(file.read())
10.4. 文件遍历与处理
使用os.walk()递归遍历目录:
import os
def process_files(root_dir):
for dirpath, dirnames, filenames in os.walk(root_dir):
print(f"Directory: {dirpath}")
for filename in filenames:
file_path = os.path.join(dirpath, filename)
print(f" File: {file_path}")
# 这里可以添加文件处理逻辑
if filename.endswith('.txt'):
process_text_file(file_path)
def process_text_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
print(f" Processing {file_path}...")
# 处理文本文件内容
# ...
# 使用示例
process_files('data')
11. 实例综合应用
11.1. 文件批量重命名
下面是一个实用的脚本,用于批量重命名目录中的文件:
import os
def batch_rename(directory, prefix, start_num=1, extension=None):
"""批量重命名目录中的文件
Args:
directory: 目标目录
prefix: 新文件名前缀
start_num: 起始编号
extension: 只重命名指定扩展名的文件(如'.txt')
"""
if not os.path.isdir(directory):
print(f"Error: '{directory}' is not a valid directory!")
return
num = start_num
for filename in os.listdir(directory):
file_path = os.path.join(directory, filename)
# 跳过子目录
if os.path.isdir(file_path):
continue
# 检查文件扩展名
if extension is not None and not filename.lower().endswith(extension.lower()):
continue
# 获取文件扩展名
_, ext = os.path.splitext(filename)
# 构建新文件名
new_filename = f"{prefix}_{num:03d}{ext}"
new_path = os.path.join(directory, new_filename)
# 重命名文件
os.rename(file_path, new_path)
print(f"Renamed: {filename} -> {new_filename}")
num += 1
# 使用示例:重命名当前目录下所有txt文件
batch_rename('.', 'document', extension='.txt')
11.2. 文件内容搜索工具
这个工具可以在目录中搜索包含特定文本的文件:
import os
def search_files(directory, search_text, extension='.txt'):
"""在目录中搜索包含特定文本的文件
Args:
directory: 要搜索的目录
search_text: 要搜索的文本
extension: 要搜索的文件扩展名
"""
results = []
for root, _, files in os.walk(directory):
for filename in files:
if not filename.lower().endswith(extension.lower()):
continue
file_path = os.path.join(root, filename)
try:
with open(file_path, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, 1):
if search_text in line:
result = {
'file': file_path,
'line_number': line_num,
'line': line.strip()
}
results.append(result)
except (UnicodeDecodeError, PermissionError):
# 跳过无法读取的文件
continue
return results
# 使用示例:在当前目录下搜索包含"Python"的txt文件
results = search_files('.', 'Python', '.txt')
for result in results:
print(f"{result['file']}:{result['line_number']} - {result['line']}")
11.3. 配置文件读写
下面是一个简单的配置文件处理类,支持读写INI风格配置:
import configparser
class ConfigManager:
def __init__(self, config_file):
self.config_file = config_file
self.config = configparser.ConfigParser()
self.load_config()
def load_config(self):
"""加载配置文件"""
if os.path.exists(self.config_file):
self.config.read(self.config_file, encoding='utf-8')
def save_config(self):
"""保存配置到文件"""
with open(self.config_file, 'w', encoding='utf-8') as file:
self.config.write(file)
def get(self, section, option, fallback=None):
"""获取配置项"""
return self.config.get(section, option, fallback=fallback)
def set(self, section, option, value):
"""设置配置项"""
if not self.config.has_section(section):
self.config.add_section(section)
self.config.set(section, option, str(value))
def get_section(self, section):
"""获取整个配置段"""
if self.config.has_section(section):
return dict(self.config.items(section))
return {}
def update_section(self, section, data):
"""更新配置段"""
if not self.config.has_section(section):
self.config.add_section(section)
for key, value in data.items():
self.config.set(section, key, str(value))
# 使用示例
config = ConfigManager('settings.ini')
# 设置配置
config.set('Database', 'host', 'localhost')
config.set('Database', 'port', '5432')
config.set('Database', 'username', 'admin')
config.set('App', 'debug', 'True')
config.set('App', 'log_level', 'info')
# 保存配置
config.save_config()
# 读取配置
host = config.get('Database', 'host', '127.0.0.1')
port = config.get('Database', 'port')
debug = config.get('App', 'debug', 'False')
print(f"Database connection: {host}:{port}")
print(f"Debug mode: {debug}")
# 获取整个配置段
db_config = config.get_section('Database')
print("Database config:", db_config)
12. 总结
本教程全面介绍了Python文件读写的方法,从基本操作到高级技巧,涵盖了文本文件、二进制文件、常见格式文件(CSV、JSON)的处理方式,以及文件和目录管理、错误处理、内存映射、临时文件、文件压缩等高级主题。通过丰富的代码示例和详细解释,您应该能够掌握:
使用open()函数和with语句安全地打开和关闭文件
多种读取文件的方法(整个文件、逐行、分块)
写入文件的基本技巧(覆盖写入、追加内容)
二进制文件的处理方法
文件指针的操作(tell()和seek())
使用os和shutil模块进行文件和目录管理
处理CSV和JSON格式文件的技巧
健壮的文件操作(异常捕获和错误处理)
高级文件操作(内存映射、临时文件、文件压缩)
实用工具开发(批量重命名、文件搜索、配置文件处理)
文件操作是Python编程中不可或缺的一部分,掌握这些技能将为您处理各种数据任务提供强大的支持。通过实践这些示例,并根据自己的需求进行扩展,您将能够高效地处理各种文件操作场景。记住,在处理文件时要特别注意资源管理和错误处理,确保程序的健壮性和可靠性。







