向后读取gzip文件

2024-04-25 20:31:40 发布

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

我想了解在不将整个文件的内容加载到内存的情况下,向后读取gzip文件的最有效方法是什么(速度和性能)。在

以下是我目前所做的,但对于非常大的文件来说效率不高:

file = 'huge_file.log.gz'
import gzip
if file.endswith('gz'):
    f = gzip.open(file)
    # reverse the file contents
    reverse_file_list = reversed(f.read().decode('utf-8').split('\n'))

我看到stackoverflow和codestate中有一些解决方案可以执行负查找,但是当文件以二进制模式打开时,不支持负查找gzip.open在

链接: Most efficient way to search the last x lines of a file in python

http://code.activestate.com/recipes/439045/

所以这个解决方案没有达到我想要的效果。在


Tags: 文件the方法内存内容情况open解决方案
3条回答

不幸的是,您必须从一开始就解析gz文件,而将它们全部解析到最后可能会很耗时。我使用一个列表缓冲区,它只弹出第一项如果reverse=True并且达到BSIZE,它将始终保存文件的最后一个BSIZE匹配,并且在一次传递中:

   BSIZE = 100; searchstr= "match in gzfile"; n = 0; buffer = []; reversed = True
   # gzf is an *.gz file in a directory
   with gzip.open(files['path'] + '/' + gzf, 'rt') as f:
        for line in f:
            if re.search(searchstr, line):
                n += 1
                buffer.append(line.strip())
                if n >= BSIZE and not reversed:
                    break
                elif n >= BSIZE:
                    buffer.pop(0)

真的没有什么好办法。gzip(deflate)压缩数据格式本质上是串行的,无论是在使用哈夫曼代码还是在之前的32K中使用匹配字符串

如果无法将其全部放入内存,则需要a)将其解压缩到磁盘,并使用未压缩表单上的seeks对其进行反向解压缩,或者b)对gzip文件执行一次解压缩,为足够小的块创建有效的随机访问入口点,然后反向执行第二次解压过程每一块。在

a)可以用tac完成,正如@Jud的回答中建议的那样,因为tac将在磁盘上创建一个临时文件来保存未压缩的内容。在

b)很复杂,需要深入了解deflate格式。它还要求为每个入口点保存32K的历史记录,无论是在内存中还是在磁盘上。在

唯一的解决方案可能是将文件解包到磁盘上并颠倒行顺序。它使用两倍的磁盘空间,但不是内存。在

您可以使用以下方法同时完成这两个步骤:

gzip -cd huge_file.log.gz | tac > huge_file.log.reversed

这样你就可以正常阅读和处理了。在

相关问题 更多 >

    热门问题