有两种基本方法可以解决这个问题:
首先,您可以编写一个read_column
带有自己显式缓冲区的函数,或者作为生成器函数:
def column_reader(fp):
buf = ''
while True:
col_and_buf = self.buf.split(',', 1)
while len(col_and_buf) == 1:
buf += fp.read(4096)
col_and_buf = buf.split(',', 1)
col, buf = col_and_buf
yield col
……或作为一个班级:
class ColumnReader(object):
def __init__(self, fp):
self.fp, self.buf = fp, ''
def next(self):
col_and_buf = self.buf.split(',', 1)
while len(col_and_buf) == 1:
self.buf += self.fp.read(4096)
col_and_buf = self.buf.split(',', 1)
self.buf = buf
return col
但是,如果您编写一个read_until
在内部处理缓冲的函数,那么您可以这样做:
next_col = read_until(fp, ',')[:-1]
ActiveState 上有多个read_until
配方。
或者,如果你mmap
是文件,你实际上是免费获得的。您可以将文件视为一个巨大的字符串并在其上使用find
(或正则表达式)。(这假设整个文件都适合您的虚拟地址空间——在 64 位 Python 构建中可能不是问题,但在 32 位构建中可能是。)
显然这些都是不完整的。他们不处理 EOF 或换行符(在现实生活中,您可能有六行一百万列,而不是一列,对吧?)等。但这应该足以说明这个想法。