是否可以在不解压缩的情况下从压缩文件中删除字符?

时间:2020-03-03 14:46:54

标签: python-3.x xml gzip tarfile

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

所以我最基本的问题是:是否甚至可以在不提取压缩文件内容的情况下完成此操作?

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

1 个答案:

答案 0 :(得分:1)

您将必须解压缩,更改然后重新压缩文件。没办法解决。

但是,这不一定包括将文件写入到存储中。您也许可以以 streaming 的方式进行所需的更改,即,所有操作仅在内存中完成,而无需在任何地方放置完整的解压缩文件。 Unix使用管道执行此类任务。

以下是有关操作方法的示例:

  1. 创建两个随机文件:
echo "hello world" > a
echo "hello world" > b
  1. 创建包含以下内容的压缩归档文件:
tar -c -z -f x.tgz a b
  1. 通过转换器将未压缩档案的内容放入管道。不幸的是,我还没有找到任何基于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

y.tgz将再次包含两个文件,但是在a中将跳过前两个字节(因此其内容将为llo world)。

您会注意到,您需要事先知道更改的结果大小。 tar旨在处理文件,因此需要将入口文件的大小写入tar信息数据报中,该数据报应位于结果文件中每个入口文件之前,因此我看不到围绕这个。对于压缩的输出,在写入所有输出并调整文件大小之后也无法跳回。

但是,正如您所说的那样,根据您的情况,这可能是可行的。

在我的简单示例案例中,您所要做的就是提供一个类似于Popen的文件状对象(可能是reader对象的输出流)。

相关问题