如何进行数据压缩和存档
数据压缩
zlib
gzip
提供简答的界面来压缩和解压压缩文件,类似GNU程序gzip和gunzip。
数据压缩由zlib模块提供。
注意:不支持由gzip和gunzip程序解压缩的其他文件格式,例如compress和pack生成的文件格式。
- 读取压缩文件
import gzip
with gzip.open('./desktop/file.txt.gz','rb') as f:
file_content = f.read()
- 创建压缩GZIP文件
import gzip
content = b"Lots of content here"
with gzip.open('./desktop/file.txt.gz','wb') as f:
file.write(content)
- GZIP压缩现有文件
import gzip
import shutil
with open('./desktop/file.txt','rb') as f_in:
with gzip.open('./desktop/file.txt.gz','wb') as f_out:
shutil.copyfileobj(f_in,f_out)
- GZIP压缩二进制字符串
import gzip
s_in = b"Lots of content here"
s_out = gzip.compress(s_in)
bz2
lzma
提供了使用LZMA压缩算法压缩和解压缩数据的类和功能,包括一个文件接口,支持xz实用程序使用的.xz和.lzma文件以及原始压缩流。
注意:LZMAFile是非线程安全的,不像bz2.BZ2File,需要使用锁来保护它。
- 读取压缩文件
import lzma
with lzma.open('file.xz') as f:
file_content = f.read()
- 创建压缩文件
import lzma
data = b"Insert Data Here"
with lzma.open('file.xz','w') as f:
f.write(data)
- 压缩内存中的数据
import lzma
data_in = b"Insert Data Here"
data_out = lzma.compress(data_in)
- 增量压缩
import lzma
lzc = lzma.LZMACompressor()
out1 = lzc.compress(b"Some data\n")
out2 = lzc.compress(b"Another piece of data\n")
out3 = lzc.compress(b"Even more data\n")
out4 = lzc.flush()
# 连接所有部分输出
result = b"".join([out1,out2,out3,out4])
- 将压缩数据写入已打开的文件
import lzma
with open('file.xz','wb') as f:
f.write(b'This data will not be compressed\n')
with lzma.open(f,'w') as lzf:
lzf.write(b'this *will* be compressed\n')
f.write(b‘Not compressed\n')
- 使用自定义过滤器链创建压缩文件
import lzma
my_filters = [
{"id": lzma.FILTER_DELTA, ’dist‘: 5},
{"id": lzma.FILTER_LZMA2,'preset': 7|lzma.PRESET_EXTREME},
]
with lzma.open('file.xz','w',filters=my_filters) as f:
f.write(b"blah blah blah")
数据存档
zipfile
zip是常见的归档和压缩标准。
zipfile提供用于创建,读取,写入,追加和列举zip文件的工具。
zipfile支持zip存档中加密文件的解密,但无法创建加密文件。
注意:zip使用Python解密而非c解密。
- ZipFile上下文管理器(支持with语句)
with ZipFile('spam.zip','w') as myzip:
myzip.write('eggs.txt')
# 即使发生异常,myzip在with语句结束之后关闭
- ZipFile.open()上下文管理器
with ZipFile('spam.zip','w') as myzip:
with myzip.open('eggs.txt') as myfile:
print(myfile.read())
zf = PyZipFile('myprog.zip')
def notests(s):
fn=os.path.basename(s)
return(not(fn=='test') or fn.startwith('test_'))
zf.writepy('myprog',filterfunc=notests)
命令行界面
# 枚举文件到创建monty.zip
python -m zipfile -c monty.zip spam.txt eggs.txt
# 枚举目录source_dir到创建monty.zip
python -m zipfile -c monty.zip source_dir/
# 解压monty.zip到目标目录target_dir
python -m zipfile -e monty.zip target_dir/
# 枚举monty.zip的文件
python -m zipfile -l monty.zip
# 测试monty.zip的有效性
python -m zipfile -t monty.zip
tarfile
tarfile可以读取和写入tar档案,包括使用gzip,bz2和lzma压缩的文件。
示例
- 解压缩整个tar存档到当前工作目录
import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()
- 使用生成器函数而非列表来提取tar存档子集
import os
import tarfile
def py_files(members):
for tarinfo in members:
if os.path.splitext(tarinfo.name)[1]=='.py':
yield tarinfo
tar = tarfile.open("smaple.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()
- 从文件名列表创建未压缩的tar存档
import tarfile
tar = tarfile.open('sample.tar','w')
for name in ['foo','bar','quux']:
tar.add(name)
tar.close()
- 使用with语句——从文件名列表创建未压缩的tar存档
import tarfile
with tarfile.open('sample.tar','w') as tar:
for name in ['foo','bar','quux']:
tar.add(name)
- 读取gzip压缩的tar存档并显示内容
import tarfile
tar = tarfile.open('sample.tar','r:gz')
for tarinfo in tar:
print(tarinfo.name, 'is',tarinfo.size,'bytes in size and is',end='')
if tarinfo.isreg():
print('a regular file.')
elif tarinfo.isdir():
print('a directory.')
else:
print('something else.')
tar.close()
- 使用以下过滤器参数创建存档并重置用户信息
import tarfile
def reset(trainfo):
tarinfo.uid = tarinfo.gid = 0
tarinfo.uname = tarinfo.gname='root'
return tarinfo
tar = tarfile.open('sample.tar.gz','w:gz')
tar.add('foo',filter=reset)
tar.close()
命令行工具
# 枚举文件到创建monty.tar
python -m tarfile -c monty.tar spam.txt eggs.txt
# 枚举目录source_dir到创建monty.tar
python -m tarfile -c monty.tar source_dir/
# 解压monty.tar到目标目录target_dir
python -m tarfile -e monty.tar target_dir/
# 枚举monty.tar的文件
python -m tarfile -l monty.tar
# 测试monty.tar的有效性
python -m tarfile -t monty.tar
# 更多信息
python -m tarfile -t monty.tar -v