我有很多带有文本文件的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并创建新文件的情况下将其“保存在原位”?
答案 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将更改,但整体文件大小不会更改(只要您保持在该单个文件的边界内。
你至少需要:
值得注意的是,位于文件末尾的中央目录是一种简洁的功能 - 因为它意味着您可以动态生成“动态”zip文件。我刚刚为一家在线销售MP3的公司做过这个,我制作了一个“动态”的zip打包器,它基本上将MP3文件与正确的ZIP标题连接在一起,这样你就可以将一堆歌曲添加到'下载列表'中,它会将MP3从家中直接流式传输到客户端 - 注入正确的头信息,最后是中央目录记录 - 从Web服务器端,它只是一系列读写,但在客户端上看起来像是一个'真正的'zip文件。