python - 如何在 Python 3 中合并两个 tar gz BinaryIO
问题描述
我有两个二进制 I/O 流(都继承BufferedIOBase),它们代表两个用 gzip 算法压缩的 tar 档案。
是否有任何有效的方法来创建第三个,即其他两个的组合?
我尝试通过将两个流转换为tarfile.Tarfile
通过fileobj
参数并将每个成员添加到第三个成员:
def merge_environment(a: Optional[BinaryIO], b: Optional[BinaryIO]) -> Optional[BinaryIO]:
"""Merge <a> and <b>, returning a new tarfile.TarFile object.
If two files in <a> and <b> have the same name, the one in <a> prevails."""
destio = io.BytesIO()
with tarfile.open(fileobj=a, mode="r:gz") as t1, \
tarfile.open(fileobj=b, mode="r:gz") as t2, \
tarfile.open(fileobj=destio, mode="w:gz") as dest:
t1_members = [m for m in t1.getmembers() if m.name != ""]
t1_names = [m.name for m in t1.members]
t2_members = [m for m in t1.getmembers() if m.name != "" and m.name not in t1_names]
for member in t1_members:
dest.addfile(member, t1.extractfile(member))
for member in t2_members:
dest.addfile(member, t2.extractfile(member))
destio.seek(0, 0)
return destio
但是,如果任何tar.gz包含目录,tarfile.extractfile()
则这不起作用,因为在目录上不起作用。
有什么解决办法吗?
解决方案
解决方案很简单,fileobj
参数 oftarfile.addfile
不是强制性的,tarinfo
就足够了:
destio = io.bytesIO()
with tarfile.open(fileobj=a, mode="r:gz") as t1, \
tarfile.open(fileobj=b, mode="r:gz") as t2, \
tarfile.open(fileobj=destio, mode="w:gz") as dest:
t1_members = [m for m in t1.getmembers()]
t1_names = t1.getnames()
t2_members = [m for m in t2.getmembers() if m.name not in t1_names]
for member in t1_members:
if member.isdir():
dest.addfile(member)
else:
dest.addfile(member, t1.extractfile(member))
for member in t2_members:
if member.isdir():
dest.addfile(member)
else:
dest.addfile(member, t2.extractfile(member))
推荐阅读
- python - Pandas 使用 NaN 旋转或重塑数据框
- terraform-provider-azure - 如何使用 terraform 设置资源健康警报条件
- c++ - 在 C++11 中无法使用互斥锁和 condition_variable 创建监视器
- node.js - Sequelize 不要在配置中使用数据库名称并尝试连接到“postgres”
- javascript - Javascript多维数组
- angular - 将 Guid 从 Angular 前端传递到 Asp.Net Core
- javascript - 如何限制用户在单击导航栏选项卡时进行导航?
- r - 通过 R 计算数字组合
- html - 在移动设备上修复搜索容器边距的问题
- python - 如何沿某个特定轴相乘两个 3d numpy 数组?