【问题标题】:Read compressed stdin读取压缩标准输入
【发布时间】:2017-06-22 16:01:23
【问题描述】:

我想要这样的电话:

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

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 建议之后出现的。

【问题讨论】:

  • 您是否尝试转储一些 f.readline() 结果以查看解压后的流是什么样的?

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


【解决方案1】:

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

【讨论】:

    【解决方案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:
    

    【讨论】:

    • TypeError: coercing to Unicode: need string or buffer, file found 提出。当标准输入已经打开时,我并不感到惊讶。
    • 好的,我用 Python 3 尝试了gzip.open,它实际上改变了一个错误。目前我有一个涉及编码的问题:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte。你还能帮忙吗?
    • 我刚刚对 Python 3 进行了实验并将 sys.stdin 替换为 sys.stdin.buffer 已解决了一个问题。你能更新你的答案吗?那么我可以接受你的解决方案。
    • tbh 目前没有列出的示例对我有用。 sys.stdin 因编码问题而失败,sys.stdin.buffer, mode='rb' 因 csv 错误而失败,在 Python 2.7 下使用 GzipFile 打开失败,并出现缺少 file 类型的 buffer 属性的错误。
    • with gzip.open(sys.stdin.buffer, 'rt') as f: 是 Python 3 下的工作解决方案。请问您能否用此语句更新您的答案?也欢迎 Python 2.7 的工作解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-03-30
    • 2012-02-17
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 2015-07-05
    • 1970-01-01
    相关资源
    最近更新 更多