求助:Python文件行数统计函数的工作原理解析
解析Python大文件行数统计代码的工作原理
我在查找文件行数统计方法时发现了如下Python函数,但不清楚其工作原理。
def _count_generator(reader): b = reader(1024 * 1024) while b: yield b b = reader(1024 * 1024) with open('test.txt', 'rb') as fp: c_generator = _count_generator(fp.raw.read) # count each new line count = sum(buffer.count(b'\n') for buffer in c_generator) print('total lines', count + 1)我知道它以字节对象读取文件,但不理解reader(1024 * 1024)的作用及整体执行逻辑,恳请帮忙解答。
一、reader(1024 * 1024) 的作用
1024 * 1024等于1MB,这个调用的意思是每次从文件中读取最多1MB的二进制数据。- 这里的
reader是传入的fp.raw.read:fp.raw是文件对象的底层二进制流,read(size)方法会读取不超过size字节的内容,返回字节串;如果文件剩余内容不足1MB,就返回剩下的所有字节;当读到文件末尾时,返回空字节串b''。 - 这种分块读取的方式,核心目的是避免一次性加载超大文件到内存,防止内存溢出。
二、整体执行逻辑
1. 生成器函数 _count_generator 的工作流程
- 这是一个生成器函数,它接收一个读取函数
reader作为参数。 - 第一次调用
reader(1MB)获取第一块数据,通过yield返回这块数据;之后进入循环,继续读取下一块数据并返回,直到reader返回空字节串b'',循环终止。 - 生成器的优势是按需生成数据,不会把整个文件内容一次性存到内存里,非常适合处理GB级别的大文件。
2. 主代码的执行步骤
with open('test.txt', 'rb') as fp:以二进制只读模式打开文件,with语句会自动处理文件关闭,避免资源泄漏;fp.raw直接操作底层二进制流,比普通文件对象的读取效率更高。c_generator = _count_generator(fp.raw.read):把fp.raw.read函数传入生成器,得到一个可迭代的生成器对象,它会不断输出1MB大小的文件数据块。sum(buffer.count(b'\n') for buffer in c_generator):遍历生成器的每个数据块,统计每个块里换行符b'\n'的数量,再把所有块的统计结果求和,得到文件中换行符的总数。print('total lines', count + 1):因为文件最后一行通常没有换行符,所以总行数等于换行符数量加1;如果最后一行恰好有换行符,结果会多算一行,但这种场景在实际中极少出现,属于通用的兼容处理。
内容的提问来源于stack exchange,提问作者Keknokz
相关产品推荐
相关产品推荐

