Python: 分块读取大文件
你好,我有一个比较大的文件想用Python来处理,但我有点不知道该怎么做。
我的文件格式是这样的:
0 xxx xxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1 xxx xxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
简单来说,我想先读取从0到1的这一部分,处理完后再继续读取1到2之间的部分。
到目前为止,我尝试用正则表达式来匹配数字,然后不断迭代,但我觉得肯定有更好的方法来实现这个。任何建议或信息都非常感谢。
6 个回答
如果"N "只能在行的开头出现,那为什么不直接用“简单”的方法呢?(听起来这个方法已经有人在用了,我只是想支持一下这个想法;-)
也就是说,可以一次读取一行,然后构建当前N对象的数据。比如说,当N=0和N=1加载完后,就一起处理它们,然后再继续下一个对(N=2,N=3)。唯一需要注意的就是不要丢掉读取的行。(决定结束条件的那一行,比如"N ",也包含了下一个N的数据)。
除非需要查找(或者输入输出缓存被禁用,或者每个项目的数据量非常大),否则我觉得没有理由不使用readline。
祝编码愉快。
这里有一些随意写的代码,可能包含多个错误。不过,它展示了使用最小副作用的方法的一般思路。
# given an input and previous item data, return either
# [item_number, data, next_overflow] if another item is read
# or None if there are no more items
def read_item (inp, overflow):
data = overflow or ""
# this can be replaced with any method to "read the header"
# the regex is just "the easiest". the contract is just:
# given "N ....", return N. given anything else, return None
def get_num(d):
m = re.match(r"(\d+) ", d)
return int(m.groups(1)) if m else None
for line in inp:
if data and get_num(line) ne None:
# already in an item (have data); current line "overflows".
# item number is still at start of current data
return [get_num(data), data, line]
# not in item, or new item not found yet
data += line
# and end of input, with data. only returns above
# if a "new" item was encountered; this covers case of
# no more items (or no items at all)
if data:
return [get_num(data), data, None]
else
return None
用法可能类似于下面的例子,其中f
代表一个打开的文件:
# check for error conditions (e.g. None returned)
# note feed-through of "overflow"
num1, data1, overflow = read_item(f, None)
num2, data2, overflow = read_item(f, overflow)
你为什么不直接用 file.read(1)
一次读取一个字符呢?
这样的话,在每次读取的时候,你可以检查一下是不是读到了字符 1
。然后你还得确保存储这个字符串的速度要快。
如果它们都在同一行,也就是说“1.”和“2.”之间没有换行符,那么你可以像这样遍历文件的每一行:
for line in open("myfile.txt"):
#do stuff
在每次循环时,这一行会被处理掉并被覆盖,这样你就可以轻松处理大文件。如果它们不在同一行:
for line in open("myfile.txt"):
if #regex to match start of new string
parsed_line = line
else:
parsed_line += line
以及你代码的其他部分。