简单说,随着时间的发展业务系统产生的数据会越来越大,这个毋容置疑,比如下面几个场景:
1. 数据分析:服务器日志、事务记录或者其他媒体视频文件通常比较大。
2. 爬虫:需要处理从web上抓取的数据集。
1. 避免内存错误:将整个文件加载到内存中通常会导致崩溃(例如MemoryError)
2. 更快的处理速度:通过增量读取文件,可以显著提高性能。
3. 资源优化:即使在内存有限的计算机上也能运行大规模任务。
以上就是简单的背景,下面我们逐步介绍处理大文件的技术。
逐行读取文件可确保在任何给定时间只有一小部分文件加载到内存中,代码示例:
with open('large_file.txt', 'r') as file: for line in file: process(line) # 处理函数这样做python会将文件对象视为迭代器,缓冲文件的小块,这种方式非常适合基于行的日志,CSV或者纯文本。
有时,需要比逐行阅读更大的灵活性,通过以固定大小的块读取文件,我们可以控制一次处理的数据量,代码示例:
def read_file_in_chunks(file_path, chunk_size=1024): with open(file_path, 'r') as file: while True: chunk = file.read(chunk_size) if not chunk: break process(chunk) # 处理函数这个方式适合不需要逐行去处理文件,另外可以根据系统的内存获得最佳性能。
生成器允许懒惰地处理数据,仅加载必要的数据。
def generate_lines(file_path): with open(file_path, 'r') as file: for line in file: yield linefor line in generate_lines('large_file.txt'): process(line)以上代码通过一次处理一行来减少内存使用量。
缓冲读取通过处理较大的内部块中的文件来提供更高级别的优化:
with open('large_file.txt', 'rb', buffering=10 * 1024 * 1024) as file: # 10 MB buffer for line in file: process(line)这种方式会减少频繁的磁盘IO操作的开销。
如果数据不断到达(例如,日志或 API),请使用流处理。
import requestsdef stream_data(url): with requests.get(url, stream=True) as response: for line in response.iter_lines(): process(line)这种方式用于实时日志监控或者API数据流。
除了上面介绍的方法,当然也有其他方式也可以实现,当然上面的方法处理日常的需求基本上也够用了,在实际使用的时候要避免一些常见的错误,例如:
1. 加载整个文件使用file.readlines(),除非文件很小,否则请避免使用
2. 忘记缓冲:未能使用缓冲 I/O 以获得更平滑的性能。
长按或扫描下方二维码,免费获取 Python公开课和大佬打包整理的几百G的学习资料,内容包含但不限于Python电子书、教程、项目接单、源码等等 推荐阅读
使用 FastAPI 整合 gRPC 构建 Python 微服务
点击 阅读原文 了解更多