【问题标题】:Is there a faster way to check if a txt file has two strings in it?有没有更快的方法来检查一个 txt 文件中是否有两个字符串?
【发布时间】:2020-02-25 15:49:13
【问题描述】:

我正在开发一个脚本来读取日志文件夹上的日志并检查每个 .txt 日志文件:

1) 如果日志包含字符串“FileData”并且
2) 如果日志没有字符串'文件数据错误'

如果满足此条件,则需要读取文件并收集第 2 行的内容。经过对该主题的一些研究,我找到了解决问题的方法,并且下面的脚本有效。问题是读取 3000 个文件需要大约 20 分钟,而且预计文件数量会增长得非常快,这种解决方案是不可行的。

import os
import mmap
Dict = {}

for log in sorted(os.listdir(log_folder)):
        with open(os.path.join(log_folder, log), 'r') as f: 
            s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
            if s.find(b'FileData') != -1 and s.find(b'Error in FileData') == -1:
                lines = [line for line in islice(f, 2)][:1]
                content = lines[1]
                Dict[log] = content

如果我只使用第一个查找 ('FileData) 运行它,它会非常快,但是当我添加第二个查找 ('FileData 中的错误') 时,时间不是线性增加的。是否有另一种方法可以更快地执行相同的操作?我试过 re.findall() 和 readlines() 但结果和这个太相似了。

谢谢!

【问题讨论】:

  • 假设文件只被程序写入(没有删除或覆盖),你可以在每个文件中保存你的位置

标签: python-3.x mmap findall readlines


【解决方案1】:

如果瓶颈是由于 IO 操作造成的,那么多线程应该会提高速度。未经测试。

import os
import threading
import mmap
Dict = {}

for log in sorted(os.listdir(log_folder)):
    threading.Thread(target=operate, args=(os.path.join(log_folder, log),)).start()

def operate(file):
    with open(file, 'r') as f: 
        s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
        if s.find(b'FileData') != -1 and s.find(b'Error in FileData') == -1:
            lines = [line for line in islice(f, 2)][:1]
            content = lines[1]
            Dict[log] = content

【讨论】:

  • 由于全局解释器锁,使用多处理可能更有意义
  • 感谢@el-banto 的回复,但它并没有真正提高速度...我相信我需要更改要处理多少文件的逻辑并使其接近或小于 3000文件以保持“可承受”的数量。
猜你喜欢
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多