【问题标题】:Why can't I create a file object from a network datastream为什么我不能从网络数据流创建文件对象
【发布时间】:2019-12-07 00:46:34
【问题描述】:

我正在从 REST API 下载 tarfile,将其写入本地文件,然后在本地提取内容。这是我的代码:

with open ('output.tar.gz', 'wb') as f:
    f.write(o._retrieve_data_stream(p).read())
with open ('output.tar.gz', 'rb') as f:
    t = tarfile.open(fileobj=f)
    t.extractall()

o._retrieve_data_stream(p) 检索文件的数据流。

这段代码运行良好,但对我来说似乎过于复杂。我想我应该能够将字节流直接读取到 tarfile 读取的文件对象中。像这样的:

with open(o._retrieve_data_stream(p).read(), 'rb') as f:
    t = tarfile.open(fileobj=f)
    t.extractall()

我意识到我的语法可能有点不稳定,但我认为它传达了我正在尝试做的事情。

但是当我这样做时,我得到一个编码错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

发生了什么事?

【问题讨论】:

    标签: python networking https tar


    【解决方案1】:

    发布是因为我在写这篇文章时解决了它。原来我需要使用BytesIO 对象。

    此代码按预期工作:

    from io import BytesIO
    
    t = tarfile.open(fileobj=BytesIO(o._retrieve_data_stream(p).read()))
    t.extractall()
    

    【讨论】:

      【解决方案2】:

      Canadian_Marine 的回答非常接近我的需要,但对于我的特殊情况还不够相当。在他们的回答中看到 open 命令中的 BytesIO 对象帮助我解决了我的问题。

      我发现有必要将请求部分从tarfile.open 中分离出来,然后将响应内容包装在tarfile.open 命令中的BytesIO 对象中。这是我的代码:

      from io import BytesIO
      import requests
      import tarfile
      
      remote_file=requests.get ('https://download.site.com/files/file.tar.gz')
      
      #Extract tarball contents to memory
      tar=tarfile.open(fileobj=BytesIO(remote_file.content))
      #Optionally print all folders / files within the tarball
      print(tar.getnames())
      tar.extractall('/home/users/Documents/target_directory/')
      

      这消除了我在使用其他方法时遇到的ValueError: embedded null byteexpected str, bytes or os.PathLike object, not _io.BytesIO 错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-08
        • 1970-01-01
        • 2019-04-07
        • 1970-01-01
        • 2016-03-11
        • 1970-01-01
        • 1970-01-01
        • 2011-11-21
        相关资源
        最近更新 更多