编辑zip文件中的文件内容

时间:2013-11-22 22:13:16

标签: python io zip

我有很多带有文本文件的zip存档。我需要找到并修改文件中的特定文本。但是我设法使用以下方法搜索文件中的所有相关行:

import os
import zipfile
from glob import glob

files = []
pattern   = "*.zip"
for dir,_,_ in os.walk(r'X:\zips'):
    files.extend(glob(os.path.join(dir,pattern)))

    for file in  files:
        root = zipfile.ZipFile(file, "r")
        for name in root.namelist():
            for line in root.read(name).split("\n"):
                if line.find("keyword") >= 0:
                   print line

我知道我可以替换该行中的关键字。但是如何在不将所有其他文本文件写入hdd,删除旧zip并创建新文件的情况下将其“保存在原位”?

1 个答案:

答案 0 :(得分:4)

如果没有使用zipfile模块开箱即用的低级别业务,你就无法做到这一点。但是,这是可能的。

首先快速解释ZIP文件结构:

来自PKWare's ZIP file structure document

  [local file header 1]
  [encryption header 1]
  [file data 1]
  [data descriptor 1]
  . 
  .
  .
  [local file header n]
  [encryption header n]
  [file data n]
  [data descriptor n]
  [archive decryption header] 
  [archive extra data record] 
  [central directory header 1]
  .
  .
  .
  [central directory header n]
  [zip64 end of central directory record]
  [zip64 end of central directory locator] 
  [end of central directory record]

文件标题如下:

  local file header signature     4 bytes  (0x04034b50)
  version needed to extract       2 bytes
  general purpose bit flag        2 bytes
  compression method              2 bytes
  last mod file time              2 bytes
  last mod file date              2 bytes
  crc-32                          4 bytes
  compressed size                 4 bytes
  uncompressed size               4 bytes
  file name length                2 bytes
  extra field length              2 bytes

  file name (variable size)
  extra field (variable size)

中央目录结构如下:

    central file header signature   4 bytes  (0x02014b50)
    version made by                 2 bytes
    version needed to extract       2 bytes
    general purpose bit flag        2 bytes
    compression method              2 bytes
    last mod file time              2 bytes
    last mod file date              2 bytes
    crc-32                          4 bytes
    compressed size                 4 bytes
    uncompressed size               4 bytes
    file name length                2 bytes
    extra field length              2 bytes
    file comment length             2 bytes
    disk number start               2 bytes
    internal file attributes        2 bytes
    external file attributes        4 bytes
    relative offset of local header 4 bytes

    file name (variable size)
    extra field (variable size)
    file comment (variable size)

每个文件都有一个文件CRC和大小,中心目录中有一个CRC和大小。因此,要修改单个文件 - 取决于您对该文件的实际操作,文件大小很可能会发生变化,并且CRC将在99%的时间内也会发生变化

这意味着该文件之后的每个文件都必须在文件中向上推,从而改变整个存档大小。

您可以通过不压缩该特定文件解决此问题 - CRC将更改,但整体文件大小不会更改(只要您保持在该单个文件的边界内。

你至少需要:

  1. 更新文件CRC
  2. 更新中央目录的CRC
  3. 值得注意的是,位于文件末尾的中央目录是一种简洁的功能 - 因为它意味着您可以动态生成“动态”zip文件。我刚刚为一家在线销售MP3的公司做过这个,我制作了一个“动态”的zip打包器,它基本上将MP3文件与正确的ZIP标题连接在一起,这样你就可以将一堆歌曲添加到'下载列表'中,它会将MP3从家中直接流式传输到客户端 - 注入正确的头信息,最后是中央目录记录 - 从Web服务器端,它只是一系列读写,但在客户端上看起来像是一个'真正的'zip文件。