繁体   English   中英

如何在Python中确定gzip压缩文件的Content-Length?

[英]How to determine the Content-Length of a gzipped file in Python?

我有一个很大的压缩文件,我想知道内容的大小而不解压缩它。 我试过这个:

import gzip
import os

with gzip.open(data_file) as f:
          f.seek(0, os.SEEK_END)
          size = f.tell()

但是我得到了这个错误

ValueError: Seek from end not supported 

我怎样才能做到这一点?

谢谢。

不幸的是,Python 2.x gzip模块似乎不支持任何确定未压缩文件大小的方法。

但是, gzip未压缩的文件大小存储为文件末尾的小端32位无符号整数: http//www.abeel.be/content/determine-uncompressed-size-gzip-file

不幸的是, 这仅适用于大小<4gb的文件,因为gzip格式只使用32位整数; 手册

import os
import struct

with open(data_file,"rb") as f:
    f.seek(-4, os.SEEK_END)
    size, = struct.unpack("<I", f.read(4))
    print size

原则上不可能在没有解压缩的情况下明确地确定gzip文件中未压缩数据的大小。 您不需要有空间来存储未压缩的数据 - 您可以随时丢弃它。 但你必须解压缩它。

如果你控制gzip文件的来源并且可以确保a)gzip文件中没有连接成员,b)未压缩数据的长度小于4 GB,并且c)在结尾处没有无关的垃圾然后只有 gzip文件才能读取gzip文件的最后四个字节,以获得具有未压缩数据长度的小端整数。

有关详细信息,请参阅此答案

这是Python代码,用于读取gzip文件并打印未压缩的长度,而无需存储或保存未压缩的数据。 它将内存使用限制为小缓冲区。 这需要Python 3.3或更高版本:

#!/usr/local/bin/python3.4
import sys
import zlib
import warnings
f = open(sys.argv[1], "rb")
total = 0
buf = f.read(1024)
while True:             # loop through concatenated gzip streams
    z = zlib.decompressobj(15+16)
    while True:         # loop through one gzip stream
        while True:     # go through all output from one input buffer
            total += len(z.decompress(buf, 4096))
            buf = z.unconsumed_tail
            if buf == b"":
                break
        if z.eof:
            break       # end of a gzip stream found
        buf = f.read(1024)
        if buf == b"":
            warnings.warn("incomplete gzip stream")
            break
    buf = z.unused_data
    z = None
    if buf == b"":
        buf == f.read(1024)
        if buf == b"":
            break
print(total)

为了总结,我需要打开huges压缩文件(> 4GB),因此Dan的技术不起作用,我想要文件的长度(行数),因此Mark Adler的技术不合适。

最后,我找到了未压缩文件的解决方案(不是最优化的但它可以工作!),它可以很容易地转换为压缩文件:

size = 0

with gzip.open(data_file) as f:
  for line in f:
    size+= 1
    pass

return size

谢谢大家,本论坛的人都非常有效!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM