2012-01-13 10 views
22

私は何もディスクに保存できない環境で働いています。私はtarファイルを引き出し、ディスクに保存せずに解凍できる必要があります。これが失敗するようだ:Pythonを使用して、純粋にメモリ内のファイルをuntarしますか?

私はこれを試してみたが、それはエラー投げる:私は、エラーラインに次のトレースバックを得る上記のコードブロックで説明したように

# fetch.py 
from cStringIO import StringIO 
import requests 
url = "http://example.com/data.tar.gz" 
response = requests.get(url) 

# ERROR is thrown here. Error shown below 
tar = tarfile.open(mode= "r:gz", fileobj = StringIO(response.content)) 

# This SHOULD break as tar.extract() saves to disk. 
# Can't tell because of error on previous line of code. 
data = tar.extract() 

を:

Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
    File "./importers/bestbuy_fetcher.py", line 23, in download_bestbuy_batch 
    tar = tarfile.open(mode= "r:gz", fileobj = StringIO(response.content)) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1662, in open 
    return func(name, filemode, fileobj, **kwargs) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1711, in gzopen 
    **kwargs) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1689, in taropen 
    return cls(name, mode, fileobj, **kwargs) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 1568, in __init__ 
    self.firstmember = self.next() 
    File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/tarfile.py", line 2324, in next 
    raise ReadError(str(e)) 
ReadError: invalid header 
+0

'response.content'が有効なgzip形式のtarファイルではないため、エラーが発生します。 – geoffspear

+0

これは意味があります:有効なgzip形式のtarファイルにするにはどうすればいいですか? – pydanny

+0

localhostから提供された有効なtar.gz。あなたは悪いtarballを受け取っているだけかもしれません。 – codysoyland

答えて

10

問題が判明だから私はそれを解決し、ファイル "data.tar.gzがtarアーカイブではなかったということだけではgzip圧縮されたファイルだった:

# fetch.py 
from cStringIO import StringIO 
import gzip 
import requests 
# Called a 'tar' file but actually a gzip file. @#$%!!! 
url = "http://example.com/data.tar.gz" 
response = requests.get(url) 

results = gzip.GzipFile(fileobj=StringIO(response.content)) 

助けた皆に感謝

+23

**これはタイトルの質問に対する回答ではないので、同様の問題を解決したい読者には非常に混乱しています。** – nealmcb

2

これは、私はエラーがtarファイルのファイル形式が間違っていることを語っていると思われる

import sys 
import zipfile 
sys.argv[0] = "/home/tom/Documents/REdata/AllListing1RES.zip" 
zip_file = zipfile.ZipFile(sys.argv[0]) 
items_file = zip_file.open('AllListing1RES.txt', 'rU') 
df = read_table(items_file, sep='\t', index_col=0) 
+2

残念ながら、要件はディスクアクセスではありません。 ;) – pydanny

+0

問題は重要ではないzipfileの使用ですが、あなたが探しているアーカイブ内のファイルを知る必要があります。 – dartdog

15

を助けるべきです。 wgetでファイルを取り出し、コマンドラインで展開してみてください。

もう一つの質問は、ファイル内容をディスクに書き込むのを止める方法について、tarfile APIを詳しく見ていくことです。 TarFile.extract()の代わりにgetnames()が必要だと思います。これは、tarファイルのすべてのメンバーの名前を返します。そして、あなたはそのメンバーの内容を取得するためにextractfileを使用することができます。

| extractfile(self, member) 
|  Extract a member from the archive as a file object. `member' may be 
|  a filename or a TarInfo object. If `member' is a regular file, a 
|  file-like object is returned. If `member' is a link, a file-like 
|  object is constructed from the link's target. If `member' is none of 
|  the above, None is returned. 
|  The file-like object is read-only and provides the following 
|  methods: read(), readline(), readlines(), seek() and tell() 

ここでは例です:

import tarfile  

# Open tarfile 
tar = tarfile.open(mode="r:gz", fileobj = file('foo.tgz')) 

# Iterate over every member 
for member in tar.getnames(): 
    # Print contents of every file 
    print tar.extractfile(member).read() 
+0

ええと、tar -zxvf data.tar.gzが "tar:Unrecognized archive format:不適切なファイルタイプまたはフォーマット"というエラーをスローします。コマンドラインではなくウィンドウから開くことができるので、状況が間違っている場所を見つけようとしています。 :P – pydanny

+0

明らかに私のフラグは間違っています。 gzip -d data.tar.gzはうまく動作します。今、なぜPythonのtarファイルがうまく動かないのかを考えようとしています。 – pydanny

+0

私はあなたと同じフラグを使用し、肯定的な結果を得たのでそれは奇妙です... – snim2

6

あなたは私たちが要求+タールを扱った際に何を試みることができる:使用|をモードでファイルを開きます。詳細はhttp://docs.python.org/library/tarfile.html#tarfile.openを参照してください。

あなたは基本的にあなたがtarfile.open(mode='r|gz', fileobj=response.raw)を使用してtarファイルを開くhttps://github.com/djeese/djeese-client/blob/master/djeese/commands/clonestatic.py#L53

でコードを見ることができます。

それは私たちのためにすごくうまくいきました。うまくいけばあなたもそうです。 。。

+0

クライアントがtarファイルのふりをしたgzipファイルを提供していたので失敗しました。純粋なgzipソリューションを使用して問題を修正しました。 :) – pydanny

関連する問題