【问题标题】:Searching strings through large file in Python在 Python 中通过大文件搜索字符串
【发布时间】:2013-10-03 15:24:40
【问题描述】:

我目前正在处理我的第一个 Python 项目,我需要解析一个 2GB 的文件。 我发现如果我一行一行地走,那会非常非常慢...... 然而缓冲方法,使用:

f = open(filename)                  
lines = 0
buf_size = 1024 * 1024
read_f = f.read 
buf = read_f(buf_size)
while buf:
    for line in buf:
      #code for string search
      print line
    buf = read_f(buf_size)

这里的打印行不打印“行”,它每行一次只打印一个字符。所以我在查找子字符串时遇到问题... 请帮忙!

【问题讨论】:

  • “for line”适用于文件,因为文件迭代器用于将输入分解为行。您在此处拥有的字符串迭代器用于将字符串分解为字符。使用更大的文件缓冲区,您将获得更好的性能,但我不能对多少做出任何承诺!返回逐行迭代文件并尝试 128K 缓冲区open(filename, "r", 128*1024)
  • 注意:您可以使用iter(callable, sentinel) 来避免while 循环:for chunk in iter(lambda: f.read(1024 * 1024), ''): #search the substring。在这种情况下,iter 将创建一个调用其callable 参数的迭代器(即callable()),直到找到sentinel 值。无论如何,读取 2GB 文件需要一些时间。假设您的硬盘可以以 200 MB/s 的速度读取,这将需要 10 秒至少,我相信 HDD 通常在 50 到 150 MB/s 之间!

标签: python parsing search find large-files


【解决方案1】:

print line 打印一个字符,因为buf 是一个字符串,并且迭代一个字符串会产生该字符串的字符为 1 个字符的字符串。

当您说逐行读取很慢时,您是如何实现读取的?如果您使用的是 readlines(),这可以解释速度慢的原因(请参阅 http://stupidpythonideas.blogspot.com/2013/06/readlines-considered-silly.html)。

文件可以在它们的行上迭代,Python 会在迭代时选择一个缓冲区大小,所以这可能适合您的需要:

for line in f:
    # do search stuff

如果您想手动指定缓冲区大小,您也可以这样做:

buf = f.readlines(buffersize)
while buf:
    for line in buf:
        # do search stuff
    buf = f.readlines(buffersize)

不过,通常两者中的第一个更好。

【讨论】:

  • 谢谢,看来我误解了什么是 buf。如果我确实执行“for line in f:”,那么迭代 2G 文件大约需要 2 分钟。这可以减少更多吗?
  • 如果您不介意将内存抛诸脑后,您可以 mmap 文件。 (见stackoverflow.com/questions/8151684/…)。除此之外,您可以手动尝试改变缓冲区大小。
【解决方案2】:

问题是buf是一个字符串……

说 buf = "abcd"

也就是说,buf[0] = a,buf[1]=b 等等。

for line in buf:
    print line

会导致 一种 b C d

这意味着在您的 for 循环中,您不会遍历“行”,而是遍历 buf 字符串的所有元素。您可以使用 readlines 或通过查找“\n”将缓冲区拆分为单行。

【讨论】:

  • 你的意思是像for line in buf: l=line.readline()这样的吗?
  • @MojingLiu 不,他的意思是for line in buf.split('\n')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多