提取 Tar 内存文件系统中的文件

Extract Tar File inside Memory Filesystem

我在使用 memoryfs 时遇到问题: https://docs.pyfilesystem.org/en/latest/reference/memoryfs.html:

我正在尝试将 tar 提取到 memoryFS 中,但我无法使用 mem_fs 因为它是一个对象并且无法获取真实/内存路径...

from fs import open_fs, copy
import fs
import tarfile

mem_fs = open_fs('mem://')

print(mem_fs.isempty('.'))

fs.copy.copy_file('//TEST_FS', 'test.tar', mem_fs, 'test.tar')

print(mem_fs.listdir('/'))

with mem_fs.open('test.tar') as tar_file:
    print(tar_file.read())
    tar = tarfile.open(tar_file) // I cant create the tar ...
    tar.extractall(mem_fs + 'Extract_Dir') // Cant extract it too...

有人可以帮助我吗?

tarfile.open 的第一个参数是文件名。您 (a) 向它传递一个打开的文件对象,并且 (b) 即使您要传递一个文件名,tarfile 对您的内存文件系统一无所知,因此无法找到文件。

幸运的是,tarfile.open 有一个 fileobj 参数接受一个打开的文件对象,所以你可以这样写:

with mem_fs.open('test.tar', 'rb') as tar_file:
    tar = tarfile.open(fileobj=tar_file)
    t.list()

请注意,您需要以二进制模式打开文件(rb)。

当然,现在你有第二个问题:虽然你可以打开和阅读档案,tarfile 模块 仍然 不知道你的 in-内存文件系统,因此尝试提取文件只会将它们提取到您的本地文件系统,这可能不是您想要的。

要提取到您的内存文件系统中,您将需要从 tar 存档成员中读取数据并自行写入。这是执行此操作的一种选择:

import fs
import os
import pathlib
import tarfile

mem_fs = fs.open_fs('mem://')
fs.copy.copy_file('/', '{}/example.tar.gz'.format(os.getcwd()),
                  mem_fs, 'example.tar.gz')

with mem_fs.open('example.tar.gz', 'rb') as fd:
    tar = tarfile.open(fileobj=fd)

    # iterate over list of members
    for member in tar.getmembers():

        # if the member is a file
        if member.isfile():

            # create any necessary directories
            p = pathlib.Path(member.path)
            mem_fs.makedirs(str(p.parent), recreate=True)

            # open the archive member
            with mem_fs.open(member.path, 'wb') as memfd, \
                    tar.extractfile(member.path) as tarfd:
                # and write the data into the memory fs
                memfd.write(tarfd.read())

tarfile.TarFile.extractfile 方法 returns 打开文件对象到 tar 存档成员,而不是将文件提取到磁盘。

请注意,如果您正在处理大文件,上述方法不是最佳解决方案(因为它会在写出之前将整个存档成员读入内存)。