分块读取文件-RAM使用,从二进制文件读取字符串

2024-05-19 01:13:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想了解在python中读取大文件时,这些方法在RAM使用方面的区别。

版本1,可在stackoverflow上找到:

def read_in_chunks(file_object, chunk_size=1024):
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data


f = open(file, 'rb')
for piece in read_in_chunks(f):
    process_data(piece)          
f.close()

版本2,我在找到上面的代码之前使用过这个:

f = open(file, 'rb')
while True:
    piece = f.read(1024)      
    process_data(piece)        
f.close()

两个版本都部分读取文件。现在的作品可以被加工。在第二个例子中,piece在每个周期都会得到新的内容,所以我认为这可以做的工作是而不是将整个文件加载到内存中。。?

但我真的不明白yield是干什么的,我很肯定我这里出了问题。有人能给我解释一下吗?


除了使用的方法外,还有其他一些东西让我困惑:

在上面的例子中,我读到的内容是由块大小1KB定义的。但是。。。如果我需要在文件中查找字符串呢?像是"ThisIsTheStringILikeToFind"

根据字符串在文件中出现的位置,可能是一个片段包含部分"ThisIsTheStr"-而下一个片段包含"ingILikeToFind"。使用这种方法不可能检测到任何一个片段中的整个字符串。

有没有一种方法可以把一个文件读成块-但不知何故关心这样的字符串?

欢迎任何帮助或想法

打招呼!


Tags: 文件方法字符串in版本truereaddata
2条回答

yield是python中用于生成表达式的关键字。这意味着,下一次调用(或迭代)函数时,执行将在上次调用它时停止的确切点上重新开始。这两个函数的行为是相同的;唯一的区别是第一个函数使用的调用堆栈空间比第二个函数多一点点。然而,第一个是更可重用的,所以从程序设计的角度来看,第一个实际上更好。

EDIT:另外一个区别是,第一个将在读取完所有数据后停止读取(应该是这样的),而第二个将只在f.read()process_data()引发异常时停止。为了使第二个程序正常工作,您需要对其进行如下修改:

f = open(file, 'rb')
while True:
    piece = f.read(1024)  
    if not piece:
        break
    process_data(piece)
f.close()

我认为最好也是最惯用的方法可能是使用内置的^{}函数和sentinel值来创建和使用iterable,如下所示。请注意,如果文件大小不是请求的块大小的确切倍数,则最后一个块大小可能小于请求的块大小。

from functools import partial

CHUNK_SIZE = 1024
filename = 'testfile.dat'

with open(filename, 'rb') as file:
    for chunk in iter(partial(file.read, CHUNK_SIZE), b''):
        process_data(chunk)

相关问题 更多 >

    热门问题