25GBのテキストファイルがあります。だからtar.gzに圧縮すると450 MBになりました。今、私はpythonからそのファイルを読み込み、テキストdata.forを処理したいと思います question を参照しましたが、私の場合、コードは機能しません。次のように :
import tarfile
import numpy as np
tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
f=tar.extractfile(member)
content = f.read()
Data = np.loadtxt(content)
エラーは次のとおりです。
Traceback (most recent call last):
File "dataExtPlot.py", line 21, in <module>
content = f.read()
AttributeError: 'NoneType' object has no attribute 'read'
また、このタスクを実行する他の方法はありますか?
docs は、Noneがextractfile()メンバーが通常のファイルまたはリンクではない場合。
可能な解決策の1つは、Noneの結果をスキップすることです:
tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
f = tar.extractfile(member)
if f is not None:
content = f.read()
tarfile.extractfile()
は、メンバーがファイルでもリンクでもない場合、None
を返すことができます。たとえば、tarアーカイブにはディレクトリまたはデバイスファイルが含まれる場合があります。修正するには:
import tarfile
import numpy as np
tar = tarfile.open("filename.tar.gz", "r:gz")
for member in tar.getmembers():
f = tar.extractfile(member)
if f:
content = f.read()
Data = np.loadtxt(content)
リンクなどの一部の特別なファイルの内容を「読み取る」ことはできませんが、tarはそれらをサポートしており、tarfileはそれらを問題なく抽出します。 tarfile
がそれらを抽出するとき、ファイルのようなオブジェクトではなくNoneを返します。また、tarballにそのような特別なファイルが含まれているため、エラーが発生します。
1つのアプローチは、抽出する前に処理しているtarballのエントリのタイプを決定することです。この情報を使用して、ファイルを「読み取る」ことができるかどうかを決定できます。これを実現するには、tarfile.getmembers()
を呼び出して、tarfile.TarInfo
sを返します。これには、tarballに含まれるファイルのタイプに関する詳細情報が含まれます。
tarfile.TarInfo
クラスには、isfile()
またはisdir()
またはtinfo.islnk()
またはtinfo.issym()
などのtarメンバーのタイプを決定するために必要なすべての属性とメソッドがあります。各メンバーで何をするかを決定します(抽出するかどうかなど)。
たとえば、これらを使用して このパッチを適用したtarfile のファイルのタイプをテストし、特別なファイルの抽出をスキップして、特別な方法でリンクを処理します。
for tinfo in tar.getmembers():
is_special = not (tinfo.isfile() or tinfo.isdir()
or tinfo.islnk() or tinfo.issym())
...
これを試してみてください
t = tarfile.open("filename.gz", "r")
for filename in t.getnames():
try:
f = t.extractfile(filename)
Data = f.read()
print filename, ':', Data
except :
print 'ERROR: Did not find %s in tar archive' % filename