参考链接: Python中的打包pack和拆包unpack参数
.pkg文件的格式?
[四字节] 固定的内容, 值不重要? [四字节] 文件数目(unsigned int)? [四字节] 文件名表 的偏移(unsigned int)? [四字节] 文件名表 的长度(字节数)(unsigned int)? ……? 中间一堆 各个文件的内容, 文件内容使用zlib压缩过? ……? 直到? 文件名表:? [两字节] 文件名长度? [文件名长度那么多字节] 文件名? [四字节] 固定的内容,值不重要? [四字节] 文件原长度? [四字节] 文件偏移? [四字节] 文件压缩后的长度? [两字节] 又一个文件名的长度? …?
例程:? 打包 PKGEncode.py? 用法 python PKGEncode.py dirname pathname.pkg?
# -*- coding: utf-8 -*-
import zlib, glob, os, sys, struct
filelist = []
class FileVisitor:
? ? def __init__(self, startDir=os.curdir):
? ? ? ? self.startDir = startDir
? ? def run(self):
? ? ? ? for dirname, subdirnames, filenames in os.walk(self.startDir, True):
? ? ? ? ? ? for filename in filenames:
? ? ? ? ? ? ? ? self.visit_file(os.path.join(dirname, filename))
? ? def visit_file(self, pathname):
? ? ? ? filelist.append({'filename':pathname, 'size':0, 'zlib_size':0, 'offset':0, 'relative_filename': pathname.replace(os.path.normpath(self.startDir)+os.sep, '')})
? ? ? ? #print filelist[-1]['relative_filename']
if __name__ == "__main__":
? ? if len(sys.argv[1]) < 3:
? ? ? ? print 'few parameter'
? ? else:
? ? ? ? source_dirname = sys.argv[1]
? ? ? ? out_filename = sys.argv[2]
? ? ? ? FileVisitor(source_dirname).run()
? ? ? ? total = len(filelist)
? ? ? ? fp = file(out_filename + '~', 'wb')
? ? ? ? fp.write('\x64\x00\x00\x00')
? ? ? ? fp.write(struct.pack('I', len(filelist)))
? ? ? ? fp.write(struct.pack('I', 0))
? ? ? ? fp.write(struct.pack('I', 0))
? ? ? ? offset = 16
? ? ? ? for index in range(total):
? ? ? ? ? ? item = filelist[index]
? ? ? ? ? ? item['offset'] = offset
? ? ? ? ? ? infile = file(item['filename'], 'rb')
? ? ? ? ? ? text = infile.read()
? ? ? ? ? ? infile.close()
? ? ? ? ? ? item['size'] = len(text)
? ? ? ? ? ? text = zlib.compress(text)
? ? ? ? ? ? item['zlib_size'] = len(text)
? ? ? ? ? ? fp.write(text)
? ? ? ? ? ? offset += item['zlib_size']
? ? ? ? ? ? print u'已压缩文件 %d/%d' % (index+1, total)
? ? ? ? filename_table_offset = offset
? ? ? ? for index in range(total):
? ? ? ? ? ? item = filelist[index]
? ? ? ? ? ? fp.write(struct.pack('H', len(item['relative_filename'])))
? ? ? ? ? ? fp.write(item['relative_filename'])
? ? ? ? ? ? fp.write('\x01\x00\x00\x00')
? ? ? ? ? ? fp.write(struct.pack('I', item['offset']))
? ? ? ? ? ? fp.write(struct.pack('I', item['size']))
? ? ? ? ? ? fp.write(struct.pack('I', item['zlib_size']))
? ? ? ? ? ? offset += 2 + len(item['relative_filename']) + 16
? ? ? ? ? ? print u'已输出路径 %d/%d' % (index+1, total)
? ? ? ? filename_table_len = offset - filename_table_offset
? ? ? ? fp.close()
? ? ? ? fp = file(out_filename + '~', 'rb')
? ? ? ? ret = file(out_filename, 'wb')
? ? ? ? fp.read(16)
? ? ? ? ret.write('\x64\x00\x00\x00')
? ? ? ? ret.write(struct.pack('I', len(filelist)))
? ? ? ? ret.write(struct.pack('I', filename_table_offset))
? ? ? ? ret.write(struct.pack('I', filename_table_len))
? ? ? ? copy_bytes = 16
? ? ? ? total_bytes = offset
? ? ? ? while True:
? ? ? ? ? ? text = fp.read(2**20)
? ? ? ? ? ? ret.write(text)
? ? ? ? ? ? copy_bytes += len(text)
? ? ? ? ? ? print u'最后的拷贝 %d%%' % (copy_bytes*100.0/total_bytes)
? ? ? ? ? ? if not text:
? ? ? ? ? ? ? ? break
? ? ? ? fp.close()
? ? ? ? ret.close()
? ? ? ? os.remove(out_filename + '~')?
解包 PKGDecode.py? 用法 python PKGDecode.py pathname.pkg dirname?
# -*- coding: utf-8 -*-
import sys, os, struct, zlib
if __name__ == "__main__":
? ? if len(sys.argv) < 3:
? ? ? ? print 'few argument'
? ? else:
? ? ? ? pkgfilename = sys.argv[1]
? ? ? ? outdirname = sys.argv[2]
? ? ? ? pkgfile = file(pkgfilename, 'rb')
? ? ? ? pkgfile.read(4)
? ? ? ? filenums, = struct.unpack('I', pkgfile.read(4))
? ? ? ? filename_table_offset, = struct.unpack('I', pkgfile.read(4))
? ? ? ? filename_table_len, = struct.unpack('I', pkgfile.read(4))
? ? ? ? pkgfile.seek(filename_table_offset)
? ? ? ? for index in range(filenums):
? ? ? ? ? ? name_len, = struct.unpack('H', pkgfile.read(2))
? ? ? ? ? ? name = pkgfile.read(name_len)
? ? ? ? ? ? pkgfile.read(4)
? ? ? ? ? ? offset, = struct.unpack('I', pkgfile.read(4))
? ? ? ? ? ? size, = struct.unpack('I', pkgfile.read(4))
? ? ? ? ? ? zlib_size, = struct.unpack('I', pkgfile.read(4))
? ? ? ? ? ? current_pos = pkgfile.tell()
? ? ? ? ? ? pkgfile.seek(offset)
? ? ? ? ? ? text = pkgfile.read(zlib_size)
? ? ? ? ? ? text = zlib.decompress(text)
? ? ? ? ? ? pkgfile.seek(current_pos)
? ? ? ? ? ? outfilename = os.path.join(outdirname, os.path.join(os.path.splitext(os.path.basename(pkgfilename))[0], name))
? ? ? ? ? ? print u'进度 [%d/%d]: ' %(index+1, filenums), os.path.join(os.path.splitext(os.path.basename(pkgfilename))[0], name)
? ? ? ? ? ? if not os.path.exists(os.path.dirname(outfilename)):
? ? ? ? ? ? ? ? os.makedirs(os.path.dirname(outfilename))
? ? ? ? ? ? file(outfilename, 'wb').write(text)?
感谢python各种库的方便? 这两个程序也可以作为自己的压缩解压工具
本文系转载,前往查看
如有侵权,请联系?cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系?cloudcommunity@tencent.com 删除。