tmpfile和gzip组合问题

9 投票
2 回答
7881 浏览
提问于 2025-04-15 21:25

我在这段代码上遇到了问题:

file = tempfile.TemporaryFile(mode='wrb')
file.write(base64.b64decode(data))
file.flush()
os.fsync(file)
# file.seek(0)
f = gzip.GzipFile(mode='rb', fileobj=file)
print f.read()

我不知道为什么它什么都不打印出来。如果我把file.seek这一行去掉注释,就会出现错误:

  File "/usr/lib/python2.5/gzip.py", line 263, in _read
    self._read_gzip_header()
  File "/usr/lib/python2.5/gzip.py", line 162, in _read_gzip_header
    magic = self.fileobj.read(2)
IOError: [Errno 9] Bad file descriptor

顺便说一下,这个版本运行得很好:

x = open("test.gzip", 'wb')
x.write(base64.b64decode(data))
x.close()
f = gzip.GzipFile('test.gzip', 'rb')
print f.read()

补充说明:关于wrb的问题。初始化时没有给我报错。Python 2.5.2。

>>> t = tempfile.TemporaryFile(mode="wrb")
>>> t.write("test")
>>> t.seek(0)
>>> t.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor

2 个回答

2

一些小提示:

  • 你不能在 wrb 模式下使用 .seek(0).read() 来操作 gzip 文件,也就是说在 wbw+b 模式下也是不行的。GzipFile 类的 __init__ 方法会根据 wrb 的第一个字符来决定是 READ 还是 WRITE 模式(在这种情况下,它会设置为 WRITE)。
  • 当你使用 f = gzip.GzipFile(mode='rb', fileobj=file) 时,真正的文件是 file,而不是 f。我在阅读 GzipFile 类的定义后才明白这一点。

对我来说,一个有效的例子是:

from tempfile import NamedTemporaryFile

import gzip


with NamedTemporaryFile(mode='w+b', delete=True, suffix='.txt.gz', prefix='f') as t_file:
    gzip_file = gzip.GzipFile(mode='wb', fileobj=t_file)
    gzip_file.write('SOMETHING HERE')
    gzip_file.close()
    t_file.seek(0)

    # Do something here with your t_file, maybe send it to an external storage or:
    print t_file.read()

希望这对某些人有帮助,花了我很多时间才让它正常工作。

13

'wrb' 这个模式是不合法的。

这个是可以正常工作的:

import tempfile
import gzip

with tempfile.TemporaryFile(mode='w+b') as f:
    f.write(data.decode('base64'))
    f.flush()
    f.seek(0)
    gzf = gzip.GzipFile(mode='rb', fileobj=f)
    print gzf.read()

撰写回答