【问题标题】:Extracting bz2 file with single file in memory使用内存中的单个文件提取 bz2 文件
【发布时间】:2015-11-20 00:02:26
【问题描述】:

我有一个压缩成 bz2 文件的 csv 文件,我试图从网站加载、解压缩并写入本地 csv 文件

# Get zip file from website
archive = StringIO()
url_data = urllib2.urlopen(url)
archive.write(url_data.read())

# Extract the training data
data = bz2.decompress(archive.read())

# Write to csv
output_file = open('dataset_' + mode + '.csv', 'w')
output_file.write(data)

在解压缩呼叫中,我收到IOError: invalid data stream。请注意,存档中包含的 csv 文件有很多字符,可能会导致一些问题。特别是,如果我尝试将文件内容放在 unicode 中,则会收到关于无法解码 0xfd 的错误。我在存档中只有一个文件,但我想知道由于未提取特定文件是否还会发生某些事情。

有什么想法吗?

【问题讨论】:

    标签: python csv stringio bz2


    【解决方案1】:

    我怀疑您收到此错误是因为您提供给 decompress() 函数的流不是有效的 bz2 流。

    您还必须在写入StringIO 缓冲区后“回退”它。请参阅以下 cmets 中的注释。如果 URL 指向有效的 bz2 文件,则以下代码(与您的代码相同,但导入和 seek() 修复除外)有效。

    from StringIO import StringIO
    import urllib2
    import bz2
    
    # Get zip file from website
    url = "http://www.7-zip.org/a/7z920.tar.bz2"  # just an example bz2 file
    
    archive = StringIO()
    
    # in case the request fails (e.g. 404, 500), this will raise
    # a `urllib2.HTTPError`
    url_data = urllib2.urlopen(url)
    
    archive.write(url_data.read())
    
    # will print how much compressed data you have buffered.
    print "Length of file:", archive.tell()
    
    # important!... make sure to reset the file descriptor read position
    # to the start of the file.
    archive.seek(0)
    
    # Extract the training data
    data = bz2.decompress(archive.read())
    
    # Write to csv
    output_file = open('output_file', 'w')
    output_file.write(data)
    

    重新:编码问题

    通常,字符编码错误会生成UnicodeError(或其表亲之一),但不会生成IOErrorIOError 表明输入有问题,例如截断,或者某些错误会阻止解压缩器完全完成其工作。

    您已从问题中省略了导入,StringIOcStringIO (根据 docs )之间的细微差别之一是 cStringIO 不能处理无法转换为的 unicode 字符串ASCII。这似乎不再成立(至少在我的测试中),但它可能在起作用。

    与 StringIO 模块不同,此模块 (cStringIO) 无法接受无法编码为纯 ASCII 字符串的 Unicode 字符串。

    【讨论】:

    • 您对seek 调用是正确的;我在发帖时正在这样做,但我必须在更改代码之前将代码复制到剪贴板。作为注释archive.getalue() 将在文件中的任何位置起作用。您对文件无效也是正确的。我在网络服务器上重新压缩了文件,问题得到了解决!
    猜你喜欢
    • 1970-01-01
    • 2014-11-14
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 2015-03-10
    • 1970-01-01
    • 2011-10-14
    相关资源
    最近更新 更多