如何在不提取所有内容的情况下访问 gzip 压缩文件夹的子文件夹中的文件?

How can I access a file that is in a subfolder of a gzip-compressed folder without extracting everything?

通过 SSH 服务器,我可以访问数据集。这个数据集被分成了几个文件,每个文件的名字都是File1.xml.gzFile2.xml.gz,等等……这些文件的命名有点误导,有两种:

  1. 既然是文件夹,严格来说我认为是一个.tar.gz文件,但是从名字看并不明显(只写着.gz)。

  2. 当你解压缩它们时,你不会直接得到 File1.xml 等,但它们都包含每个第一个(子)文件夹(没有别的),这又包含第二个子文件夹(没有别的),这个是第三个子文件夹(没有别的),这个最后包含第四个子文件夹,File1.xml(没有别的)位于其中。

    我在文件夹结构的图片中画出了这个:

    正是我要访问的最底层的这个文件

我的问题: 我不能删除(显然是多余的)文件夹,服务器上几乎没有任何 space 和这些文件非常大,所以我无法解压缩它们。因此我想逐行读取文件的内容。

我想我知道如何找到嵌入在多个子文件夹中的文件:

for root, dirs, files in os.walk(directory, topdown=False):
    for file in files:
        if file.startswith('file') and file.endswith('.xml'):
            # do something with file

而且我知道如何在不显式解压缩的情况下读取压缩文件:

with gzip.open('path to file1.xml.gz', 'rt', encoding='utf-8') as file1:
    for line in file1:
        print(line)

但是访问压缩文件夹的子文件夹中的文件?这可能吗?

使用tarfile,打开模式"r|gz"。使用 next() 直到你得到你想要的,然后在那个成员上 extractfile() 到 return 你可以读取的缓冲流。

>>> import tarfile
>>> t = tarfile.open("file.gz","r|gz")
>>> t.next()
<TarInfo 'a' at 0x1044d3b38>
>>> t.next()
<TarInfo 'a/b' at 0x1044d39a8>
>>> t.next()
<TarInfo 'a/b/c' at 0x1044d38e0>
>>> t.next()
<TarInfo 'a/b/c/d' at 0x1044d3a70>
>>> m = t.next()
>>> m.name
'a/b/c/d/file'
>>> f = t.extractfile(m)
>>> f.readline()
b'this\n'
>>> f.readline()
b'is\n'
>>> f.readline()
b'a\n'
>>> f.readline()
b'test\n'
>>> f.readline()
b''