提取 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 存档成员,而不是将文件提取到磁盘。
请注意,如果您正在处理大文件,上述方法不是最佳解决方案(因为它会在写出之前将整个存档成员读入内存)。
我在使用 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 存档成员,而不是将文件提取到磁盘。
请注意,如果您正在处理大文件,上述方法不是最佳解决方案(因为它会在写出之前将整个存档成员读入内存)。