Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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 3.x 是否可以在不提取压缩文件的情况下从压缩文件中删除字符?_Python 3.x_Xml_Gzip_Tarfile - Fatal编程技术网

Python 3.x 是否可以在不提取压缩文件的情况下从压缩文件中删除字符?

Python 3.x 是否可以在不提取压缩文件的情况下从压缩文件中删除字符?,python-3.x,xml,gzip,tarfile,Python 3.x,Xml,Gzip,Tarfile,我有一个大约200 MB的压缩文件,格式是tar.gz文件。我知道我可以提取其中的xml文件。它包含几个小的5 GB xml文件和一个5 GB xml文件。我正在尝试从xml文件中删除某些字符 所以我最基本的问题是:甚至不提取压缩文件的内容就可以实现这一点吗 我正在尝试加快读取xml文件以查找要删除的字符的过程。您必须解压缩、更改,然后重新压缩文件。这是没有办法的 但是,这不一定包括将文件写入存储器。您可能能够以流式方式进行您喜欢的更改,即,所有操作都只在内存中完成,而不需要在某个地方有完整的解

我有一个大约200 MB的压缩文件,格式是tar.gz文件。我知道我可以提取其中的xml文件。它包含几个小的5 GB xml文件和一个5 GB xml文件。我正在尝试从xml文件中删除某些字符

所以我最基本的问题是:甚至不提取压缩文件的内容就可以实现这一点吗


我正在尝试加快读取xml文件以查找要删除的字符的过程。

您必须解压缩、更改,然后重新压缩文件。这是没有办法的

但是,这不一定包括将文件写入存储器。您可能能够以流式方式进行您喜欢的更改,即,所有操作都只在内存中完成,而不需要在某个地方有完整的解压缩文件。Unix使用管道执行此类任务

下面是一个如何执行此操作的示例:

  • 创建两个随机文件:
  • 创建包含以下内容的压缩存档:
  • 通过转换器将未压缩存档的内容传输到管道中。不幸的是,我没有找到任何基于shell的方法来实现这一点,但您也在标记中指定了Python,使用
    tarfile
    模块可以实现这一点:
  • 这是文件
    tar.py

    #!/usr/bin/env python3
    
    import sys
    import tarfile
    
    tar_in  = tarfile.open(fileobj=sys.stdin.buffer,  mode='r:gz')
    tar_out = tarfile.open(fileobj=sys.stdout.buffer, mode='w:gz')
    
    for tar_info in tar_in:
      reader = tar_in.extractfile(tar_info)
      if tar_info.path == 'a':  # my example file names are "a" and "b"
        # now comes the code which makes our change:
        # we just skip the first two bytes in each file:
        reader.read(2)  # skip two bytes
        tar_info.size -= 2  # reduce size in info object as well
      # add the (maybe changed) file to the output:
      tar_out.addfile(tar_info, reader)
    
    tar_out.close()
    tar_in.close()
    
    这可以这样称呼:

    ./tar.py < x.tgz > y.tgz
    
    /tar.pyy.tgz
    
    y.tgz
    将再次包含这两个文件,但在
    a
    中,将跳过前两个字节(因此其内容将是
    lloworld

    您会注意到,您需要事先知道更改的结果大小
    tar
    设计用于处理文件,因此它需要将条目文件的大小写入tar info数据报,该数据报位于结果文件中每个条目文件的前面,因此我看不出有任何解决方法。对于压缩输出,写入所有输出并调整文件大小后也不可能向后跳

    但正如你提出的问题,这在你的情况下是可能的


    在我的简单示例中,您需要做的就是提供一个类似文件的对象(可以是
    Popen
    对象的输出流),比如
    reader

    您想更改压缩文件的内容,但不想解压缩(然后再重新压缩)它?压缩不是这样工作的。当你说“提取”时,你是说“写入磁盘”吗?如果是这样的话,应该可以在不向文件系统写入任何内容的情况下实现您想要的功能,但是您必须解压缩数据,删除不需要的字符,然后重新压缩它。如果它没有写入磁盘,它在哪里解压缩?在记忆中?如果是这样,在处理大型文件时,这可能会成为一个问题?我正在努力更好地理解gzip。
    #!/usr/bin/env python3
    
    import sys
    import tarfile
    
    tar_in  = tarfile.open(fileobj=sys.stdin.buffer,  mode='r:gz')
    tar_out = tarfile.open(fileobj=sys.stdout.buffer, mode='w:gz')
    
    for tar_info in tar_in:
      reader = tar_in.extractfile(tar_info)
      if tar_info.path == 'a':  # my example file names are "a" and "b"
        # now comes the code which makes our change:
        # we just skip the first two bytes in each file:
        reader.read(2)  # skip two bytes
        tar_info.size -= 2  # reduce size in info object as well
      # add the (maybe changed) file to the output:
      tar_out.addfile(tar_info, reader)
    
    tar_out.close()
    tar_in.close()
    
    ./tar.py < x.tgz > y.tgz