簡體   English   中英

在 Python 中讀取 .tar.gz 文件

[英]Read .tar.gz file in Python

我有一個 25GB 的文本文件。 所以我將它壓縮到 tar.gz 並變成了 450 MB。 現在我想從 python 讀取該文件並處理文本數據。為此我提到了問題 但在我的情況下,代碼不起作用。 代碼如下:

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'

另外,還有其他方法可以完成此任務嗎?

文檔告訴我們,如果成員不是常規文件或鏈接,則extractfile()將返回None

一種可能的解決方案是跳過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)

你可以試試這個

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

您無法“讀取”某些特殊文件(例如鏈接)的內容,但 tar 支持它們並且 tarfile 可以正常提取它們。 tarfile提取它們時,它不會返回類似文件的對象而是 None。 你會得到一個錯誤,因為你的 tarball 包含這樣一個特殊的文件。

一種方法是在提取之前確定您正在處理的 tarball 中條目的類型:有了這些信息,您就可以決定是否可以“讀取”文件。 您可以通過調用tarfile.getmembers()返回tarfile.TarInfo來實現此tarfile.TarInfo ,其中包含有關 tarball 中包含的文件類型的詳細信息。

tarfile.TarInfo類具有確定 tar 成員類型所需的所有屬性和方法,例如isfile()isdir()tinfo.islnk()tinfo.issym() ,然后相應地決定如何處理每個成員(提取與否等)。

例如,我使用這些來測試此修補 tarfile 中的文件類型,以跳過以特殊方式提取特殊文件和處理鏈接的過程:

for tinfo in tar.getmembers():
    is_special = not (tinfo.isfile() or tinfo.isdir()
                      or tinfo.islnk() or tinfo.issym())
...

我的需求:

  1. 蟒蛇3。
  2. 我的 tar.gz 文件由多個utf-8文本文件和目錄組成。
  3. 需要從所有文件中讀取文本行。

問題:

  1. tar.getmembers() 返回的 tar 對象可能是None
  2. 內容extractfile(fname)返回的是一個字節字符串(例如 b'Hello\\t\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd')。 Unicode 字符顯示不正確。

解決方案:

  1. 首先檢查 tar 對象的類型。 我參考了 tarfile lib文檔中的示例。 (搜索“如何讀取 gzip 壓縮的 tar 存檔並顯示一些成員信息”)
  2. 從字節 str 解碼為普通 str。 參考- 投票最多的答案)

代碼:

with tarfile.open("sample.tar.gz", "r:gz") as tar:
for tarinfo in tar:
    logger.info(f"{tarinfo.name} is {tarinfo.size} bytes in size and is: ")
    if tarinfo.isreg():
        logger.info(f"Is regular file: {tarinfo.name}")
        f = tar.extractfile(tarinfo.name)  
        # To get the str instead of bytes str
        # Decode with proper coding, e.g. utf-8
        content = f.read().decode('utf-8', errors='ignore')
        # Split the long str into lines
        # Specify your line-sep: e.g. \n
        lines = content.split('\n')
        for i, line in enumerate(lines):
            print(f"[{i}]: {line}\n")
    elif tarinfo.isdir():
        logger.info(f"Is dir: {tarinfo.name}")
    else:
        logger.info(f"Is something else: {tarinfo.name}.")

在 Jupyter notebook 中,你可以像下面這樣

!wget -c http://qwone.com/~jason/20Newsgroups/20news-bydate.tar.gz -O - | tar -xz

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM