读压缩标准输入

时间:2017-06-22 16:01:24

标签: python python-3.x file unix gzip

我想打电话:

pv -ptebar compressed.csv.gz | python my_script.py

Inside my_script.py我想解压缩compressed.csv.gz并使用Python csv解析器解析它。我希望这样的事情:

import csv
import gzip
import sys


with gzip.open(fileobj=sys.stdin, mode='rt') as f:
    reader = csv.reader(f)
    print(next(reader))
    print(next(reader))
    print(next(reader))

当然它不起作用,因为gzip.open没有fileobj参数。你能提供一些解决这个问题的实例吗?

更新

Traceback (most recent call last):
  File "my_script.py", line 8, in <module>
    print(next(reader))
  File "/usr/lib/python3.5/gzip.py", line 287, in read1
    return self._buffer.read1(size)
  File "/usr/lib/python3.5/_compression.py", line 68, in readinto
    data = self.read(len(byte_view))
  File "/usr/lib/python3.5/gzip.py", line 461, in read
    if not self._read_gzip_header():
  File "/usr/lib/python3.5/gzip.py", line 404, in _read_gzip_header
    magic = self._fp.read(2)
  File "/usr/lib/python3.5/gzip.py", line 91, in read
    self.file.read(size-self._length+read)
  File "/usr/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

在应用@Rawing建议后,上面出现了追溯。

2 个答案:

答案 0 :(得分:2)

在python 3.3+中,您可以将文件对象传递给gzip.open

  

filename参数可以是实际文件名(str或bytes对象),也可以是要读取或写入的现有文件对象。

因此,如果您省略fileobj=

,那么您的代码应该可行
with gzip.open(sys.stdin, mode='rt') as f:

或者,更有效的解决方案:

with gzip.open(sys.stdin.buffer, mode='rb') as f:

如果由于某些奇怪的原因你使用的是3.3以上的python,你可以直接调用gzip.GzipFile constructor。但是,这些旧版本的gzip模块不支持在文本模式下打开的文件,因此我们将使用sys.stdin的底层缓冲区:

with gzip.GzipFile(fileobj=sys.stdin.buffer) as f:

答案 1 :(得分:2)

使用gzip.open(sys.stdin.buffer, 'rt')修复了Python 3的问题。