Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在不写入磁盘的情况下提取lzma压缩tar存档成员_Python_Lzma_Tarfile - Fatal编程技术网

Python 在不写入磁盘的情况下提取lzma压缩tar存档成员

Python 在不写入磁盘的情况下提取lzma压缩tar存档成员,python,lzma,tarfile,Python,Lzma,Tarfile,我有一个2焦油深的嵌套焦油文件。最外层的tar是gpg加密的而不是压缩的。内部焦油是lzma。使用磁盘最里面的tar,我没有任何问题。使用tarfile.open()将最内部的tar.xz文件直接传递到,就像get_lzma一样。该行后面的代码执行时不会出错。我可以提取tar成员和json.load()数据 这是一个小文件,数据很敏感。当我使用它时,它必须放在磁盘上,所以我不想解密它并将最里面的tar提取到磁盘上。所以我想访问内存中的成员。我可以解密到gpg文件,并在get_lzma.getme

我有一个2焦油深的嵌套焦油文件。最外层的tar是gpg加密的而不是压缩的。内部焦油是lzma。使用磁盘最里面的tar,我没有任何问题。使用tarfile.open()将最内部的tar.xz文件直接传递到
,就像get_lzma
一样。该行后面的代码执行时不会出错。我可以提取tar成员和
json.load()
数据

这是一个小文件,数据很敏感。当我使用它时,它必须放在磁盘上,所以我不想解密它并将最里面的tar提取到磁盘上。所以我想访问内存中的成员。我可以解密到gpg文件,并在get_lzma.getmembers()中为成员
返回我期望的tarinfo对象,因此该成员似乎在那里,我对此无能为力。当我运行
extractfile()
时,我无法
读取它返回的结果

在这一点上,我只是好奇为什么这不起作用

如果文件结构不清楚,磁盘上就是这样的:

file.tar.gpg <- is a tar file
 file.tar.xz <- is a compressed tar file
   member1
   memberN

离这个问题还有一天,我对这个问题的理解似乎就清楚了。我会解释我的想法和我的发现

tldr我把tarinfo、tarfile和exfileobjects搞混了

根据OP,传递到
open()
的文件在封面下表示为
。因此,让代码处理未加密的文件和
open()
,实际上只能证明文件没有损坏。所以没有问题,我不会再提了

按照OP中的代码示例,调用
decrypted_data.data
decrypted_data
对象返回原始字节字符串。这些原始字节是我的2个tar文件。解压tar和压缩tar嵌套结构。字符串以
b'myfile.tar.xz\x00\x00\x00\.
等开头。我们将其包装为一个bytes对象
io.BytesIO(decrypted_data.data)
,这样我们就有了一个可以使用的接口,并可以将其初始传递到
tarfile.open()
。到目前为止还不错,但这就是事情开始出错的地方

我决定在下面的代码中使用2个上下文管理器。在OP中,我两次调用了
tarfile.open()
,我想我一定假设有一个提取操作和
mode='r'
。您可以看到,我现在在每个上下文管理器的
成员上对
extractfile()
进行了两次调用。第一个
extractfile()
从未压缩的tar中提取tar.xz。这是我最终作为
mode=r:xz
传递给下一个上下文管理器的
ExFileObject
“文件”。在OP中,它是一个
TarInfo
对象,而不是提取的数据,这是错误的

第二次调用
extractfile()
是在第二个上下文管理器的
member
上完成的,以便从
myfile.tar.xz
获取
可读的\u members\u值

with tarfile.open(fileobj=io_bytes_file_like_object, mode='r') as uncompressed_tar_file:

    # uncompressed_tar_file is tarfile.TarFile object
    for member in uncompressed_tar_file.getmembers():

      # member is TarInfo object
        tar_file_object = uncompressed_tar_file.extractfile(member)

        # tar_file_object is ExFileObject
        with tarfile.open(fileobj=tar_file_object, mode='r:xz', debug=3, errorlevel=2) as lzma_compressed_tar_file:
            for member in lzma_compressed_tar_file.getmembers():
                if member.isfile():
                    readable_members_value = lzma_compressed_tar_file.extractfile(member)

                    # now works where it failed before equivalent to something like file_o.read() in OP
                    print(readable_members_value.read())

                    decoded_readable_member_value = readable_member_value.read().decode("utf-8")
                    json_data = json.loads(decoded_readable_member_value)
                    print(json_data)
除了最后几行代码外,其余代码几乎完全相同。从OP中的变量名可以看出,我希望
file\o
是一个文件对象
json.load(file_o)
将对文件指针起作用,但在本例中,
readable_成员。read()
返回字节文本
b'
,因此实际上我不需要
json.load()

   with open(gpg_encrypted_tar_archive, 'rb') as f: 
        try:
            decrypted_data = gpg.decrypt_file(f, passphrase=passph)
            assert decrypted_data.ok
        except AssertionError:
            print(f"Decryption failed with message '{decrypted_data.status}' and status '{decrypted_data.ok}'")

        io_bytes_file_like_object = io.BytesIO(decrypted_data.data)

        # untar the parent archive
        tarfile.open(fileobj=io_bytes_file_like_object, mode='r')

        with tarfile.open(fileobj=io_bytes_file_like_object, mode='r:xz', debug=3, errorlevel=2) as get_lzma:

            for member in get_lzma.getmembers():

                if member.isfile():
                    file_o = get_lzma.extractfile(member)
                    json.load(file_o)
with tarfile.open(fileobj=io_bytes_file_like_object, mode='r') as uncompressed_tar_file:

    # uncompressed_tar_file is tarfile.TarFile object
    for member in uncompressed_tar_file.getmembers():

      # member is TarInfo object
        tar_file_object = uncompressed_tar_file.extractfile(member)

        # tar_file_object is ExFileObject
        with tarfile.open(fileobj=tar_file_object, mode='r:xz', debug=3, errorlevel=2) as lzma_compressed_tar_file:
            for member in lzma_compressed_tar_file.getmembers():
                if member.isfile():
                    readable_members_value = lzma_compressed_tar_file.extractfile(member)

                    # now works where it failed before equivalent to something like file_o.read() in OP
                    print(readable_members_value.read())

                    decoded_readable_member_value = readable_member_value.read().decode("utf-8")
                    json_data = json.loads(decoded_readable_member_value)
                    print(json_data)