我有一个大的压缩文件,想知道内容的大小而不需要解压缩它。我尝试了以下方法:
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
我该怎么做呢?
谢谢。
我有一个大的压缩文件,想知道内容的大小而不需要解压缩它。我尝试了以下方法:
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
不幸的是,由于gzip
格式仅使用32位整数,因此仅适用于文件大小<4gb;请参阅手册。
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
#!/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)
decompressobj
的 eof
方法是在 3.3 版本中添加的,它需要识别何时到达 gzip 流的末尾。 - Mark Adlersize = 0
with gzip.open(data_file) as f:
for line in f:
size+= 1
pass
return size
谢谢大家,这个论坛的人都非常高效!
f.tell()
返回字节数而不是行数。 - Mark Adler
os.SEEK_END
是用于lseek
的。这可能是你需要的。 - llrsfile
文档,@Llopis,os.SEEK_
常量确实是与file.seek
一起使用的正确选项。此外,os.lseek
在这里不起作用,因为gzip
文件对象没有底层的POSIX级文件描述符。 - Dan Lenski