Python3:读取和处理超大文件

2024-04-19 02:04
文章标签 读取 处理 python3 超大

本文主要是介绍Python3:读取和处理超大文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在日常工作中,文件对象是我们常接触到的可迭代类型之一。一般用 for 循环遍历一个文件对象,可以逐行读取它的内容。但这种方式在碰到大文件时,可能会出现一些奇怪的效率问题。

需求:

小明是一位 Python 初学者,在学习了如何用 Python 读取文件后,他想要做一个小练习:计算某个文件中数字字符(0~9)的数量。

场景1:小文件处理

假设现在有一个测试用的小文件 small_file.txt,里面包含了一行行的随机字符串:

feiowe9322nasd9233rl
aoeijfiowejf8322kaf9a
...

代码示例:file_process.py

def count_digits(fname):"""计算文件里包含多少个数字字符"""count = 0with open(fname) as file:for line in file:for s in line:if s.isdigit():count += 1return countfname = "./small_file.txt"
print(count_digits(fname))

运行结果:

# 运行脚本
python3 ./file_process.py# 输出结果
13

场景2:大文件处理

假设现在我们的大文件big_file.txt,大小有5G,且所有的文本都在一行。

大文件 big_file.txt

df2if283rkwefh... <剩余 5 GB 大小> ...

却发现同样的程序花费了一分多钟才给出结果,并且整个执行过程耗光了笔记本电脑的全部 4G 内存。

问题分析:

为什么同一份代码用于大文件时,效率就会变低这么多呢?原因就藏在小明读取文件的方法里。

在代码里所使用的文件读取方式,可谓 Python 里的“标准做法”:首先用 with open (fine_name) 上下文管理器语法获得一个文件对象,然后用 for 循环迭代它,逐行获取文件里的内容。为什么这种文件读取方式会成为标准?这是因为它有两个好处:

(1) with 上下文管理器会自动关闭文件描述符

(2) 在迭代文件对象时,内容是一行一行返回的,不会占用太多内存。

不过这套标准做法虽好,但不是没有缺点。假如被读取的文件里根本就没有任何换行符,那么上面列的第 (2) 个好处就不再成立。缺少换行符以后,程序遍历文件对象时就不知道该何时中断,最终只能一次性生成一个巨大的字符串对象,白白消耗大量时间和内存。这就是 count_digits() 函数在处理 big_file.txt 时变得异常缓慢的原因。

要解决这个问题,我们需要把这种读取文件的“标准做法”暂时放到一边。

解决方法:

使用 while 循环加 read() 方法分块读取。

除了直接遍历文件对象来逐行读取文件内容外,我们还可以调用更底层的 file.read() 方法。与直接用循环迭代文件对象不同,每次调用 file.read(chunk_size), 会马上读取从当前游标位置往后 chunk_size 大小的文件内容,不必等待任何换行符出现。有了 file.read() 方法的帮助,优化后的代码:

def count_digits_v2(fname):"""计算文件里包含多少个数字字符,每次读取 8 KB"""count = 0block_size = 1024 * 8with open(fname) as file:while True:chunk = file.read(block_size)# 当文件没有更多内容时,read 调用将会返回空字符串 ''if not chunk:breakfor s in chunk:if s.isdigit():count += 1return countfname = "./big_file.txt"
print(count_digits_v2(fname))

在新函数中,我们使用了一个 while 循环来读取文件内容,每次最多读 8 KB,程序不再需要在内存中拼接长达数吉字节的字符串,内存占用会大幅降低。

(吉字节是一种数据存储单位,通常用于表示大容量存储设备的容量大小。它等于1024^3(1,073,741,824)字节,或者1,024兆字节。在计算机领域,常用于描述大型文件、程序或数据集的大小,例如硬盘容量、内存容量等。)

这篇关于Python3:读取和处理超大文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/916370

相关文章

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos