## 基础打开模式
文件操作核心就三步:open、读写、close。先看最常用的模式:
# r - 只读(默认),文件必须存在
# w - 写入,会清空文件内容,不存在则创建
# a - 追加,写入到末尾,不存在则创建
# x - 创建写入,文件已存在会报错
# b - 二进制模式,配合r/w/a使用
# + - 读写模式,配合r/w/a使用
f = open('test.txt', 'r')
content = f.read()
f.close()
## with语句:自动关闭
手动close容易忘,用with自动处理:
with open('test.txt', 'r') as f:
content = f.read()
# 离开缩进自动close
## 读取方式
with open('test.txt', 'r', encoding='utf-8') as f:
# 全部读取到字符串
content = f.read()
# 读取指定字符数
chunk = f.read(100)
# 读取一行
line = f.readline()
# 读取所有行到列表
lines = f.readlines()
# 迭代器方式,适合大文件
for line in f:
print(line.strip())
大文件千万别用read()或readlines(),会撑爆内存。用迭代器逐行处理:
with open('large_log.txt', 'r', encoding='utf-8') as f:
for line in f:
process(line) # 每行处理完就释放
## 写入方式
# 覆盖写入
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('第一行\n')
f.write('行\n')
# 追加写入
with open('log.txt', 'a', encoding='utf-8') as f:
f.write(f'{datetime.now()}: 操作完成\n')
# 写入多行
lines = ['a\n', 'b\n', 'c\n']
with open('list.txt', 'w') as f:
f.writelines(lines)
write不会自动换行,需要自己加\n。writelines也不加,得在列表里带好。
## 二进制读写
图片、音频、压缩包必须用二进制模式:
# 读二进制
with open('image.jpg', 'rb') as f:
data = f.read()
# 写二进制
with open('copy.jpg', 'wb') as f:
f.write(data)
# 逐块复制大文件
with open('big_file.bin', 'rb') as src, open('copy.bin', 'wb') as dst:
while True:
chunk = src.read(8192) # 8KB一块
if not chunk:
break
dst.write(chunk)
## 文件指针操作
with open('test.txt', 'r') as f:
print(f.tell()) # 当前指针位置,0
f.read(10)
print(f.tell()) # 10
f.seek(0) # 回到开头
f.seek(5) # 跳到第5个字符
f.seek(-3, 2) # 从末尾往前3个字符
seek的个参数:0开头,1当前位置,2末尾。文本模式下只能用0。
## 常见坑点
编码问题:不指定encoding在Windows上默认用gbk,Linux用utf-8。跨平台时显式指定utf-8:
with open('data.txt', 'r', encoding='utf-8') as f:
pass
换行符:Windows是\r\n,Linux是\n。文本模式下Python会自动转换,二进制模式不会。
文件不存在:
– r模式:FileNotFoundError
– w/a模式:自动创建
– x模式:FileExistsError
混合读写:用r+或者w+模式,但要注意指针位置:
# 读取后修改
with open('test.txt', 'r+') as f:
content = f.read()
f.seek(0)
f.write('new content')
f.truncate() # 截断到当前位置,避免旧内容残留
## 实用技巧
临时文件:处理完自动删除
from tempfile import NamedTemporaryFile
with NamedTemporaryFile(delete=True, suffix='.tmp') as f:
f.write(b'temp data')
# 处理完成后自动清理
文件是否存在:用os.path或pathlib
import os
from pathlib import Path
if os.path.exists('test.txt'):
pass
if Path('test.txt').is_file():
pass
读取配置文件:生产环境可以用configparser,简单场景直接读:
# config.ini
# [db]
# host = 127.0.0.1
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
host = config['db']['host']
实际部署时,我习惯把配置文件放在雨云服务器上,它们的高可用存储挂载到多个节点,改配置不用重启服务。雨云的云盘IO性能不错,日志写入基本不卡顿。
文件锁:多进程写同一文件时用fcntl或portalocker,避免数据错乱。
内存映射:超大文件用mmap,像操作内存一样操作文件:
import mmap
with open('huge_file.bin', 'r+b') as f:
with mmap.mmap(f.fileno(), 0) as mm:
print(mm[:100]) # 像操作字节数组
文件读写没什么玄学,记住三点:明确模式、用with、注意编码。处理大文件别一次全读进来,其他就是记几个常用API的事。
雨云是国内一家老牌云服务商,提供高性价比的云服务器和虚拟主机。我用它部署了好几个项目,速度和稳定性都不错。通过 https://www.rainyun.com/SAJA_ 注册可以领一张 5折优惠券,有需要的朋友可以看看。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END



暂无评论内容