我需要完全在内存中更新tar存档。原因是我有一个与tar文件(包含敏感数据)的加密包,我无法将未加密的表单(tar存档)保存到磁盘。 现在,我能够很好地阅读它,但是保存新文件会导致意外的结果
在此主题中将不再讨论加密。这只是一个简短的描述,说明我需要以我现在的方式做事
我的目标是打开一个tar文件,从中删除一些文件,添加一些其他文件并保存新的.tar
文件。
我需要使用BytesIO
对象来完成它。但在一个简单得多的场景中,我甚至无法从以前的tar文件创建新的tar文件
在磁盘上读取和保存(复制)tar文件的简单方案:
$ ls -l
-rw-r--r-- 1 myuser myuser 3595 Jun 3 23:10 archive.pem
-rw-r--r-- 1 myuser myuser 50 Jun 3 23:19 gibberish
-rw-r--r-- 1 myuser myuser 1024 Jun 3 13:07 some_file.log
$ tar cfz example.tar.gz *
$ ls -l
-rw-r--r-- 1 myuser myuser 3595 Jun 3 23:10 archive.pem
-rw-r--r-- 1 myuser myuser 3059 Jun 4 09:08 example.tar.gz
-rw-r--r-- 1 myuser myuser 50 Jun 3 23:19 gibberish
-rw-r--r-- 1 myuser myuser 1024 Jun 3 13:07 some_file.log
$ tar tfz example.tar.gz
archive.pem
gibberish
some_file.log
使用简单的Python代码读取example.tar.gz
并保存一个新的example.tar
(只是一个副本):
import tarfile
with tarfile.open('example.tar.gz', 'r') as tr, tarfile.open('example.tar', 'w') as tw:
for m in tr.getmembers():
print(f"{m.name} size = {m.size}")
tw.addfile(m)
运行此代码的输出为:
archive.pem size = 3595
gibberish size = 50
some_file.log size = 1024
新目录如下所示:
$ ls -l
-rw-r--r-- 1 myuser myuser 3595 Jun 3 23:10 archive.pem
-rw-r--r-- 1 myuser myuser 10240 Jun 4 09:16 example.tar
-rw-r--r-- 1 myuser myuser 3059 Jun 4 09:08 example.tar.gz
-rw-r--r-- 1 myuser myuser 50 Jun 3 23:19 gibberish
-rw-r--r-- 1 myuser myuser 1024 Jun 3 13:07 some_file.log
$ tar tf example.tar
some_file.log
只列出一个文件,新tar文件的大小始终为10k。 文件的大部分都用“\0”字节填充
如果上述代码工作正常,作为一个简化示例,我真正想做的是:
通过删除一个文件并添加另一个文件来更新存档:
import tarfile
from io import BytesIO
def _update_tar(tarfileobj, file_to_add, file_to_remove):
outio = BytesIO()
with tarfile.open(fileobj=tarfileobj) as _in, tarfile.TarFile(
fileobj=outio, mode="w"
) as _out:
for member in _in.getmembers():
print(f"Read {member.name} from archive.")
if member.name != file_to_remove:
print(f"Add {member.name} to the new archive!")
_out.addfile(member)
_out.add(file_to_add)
outio.seek(0)
return outio
tarbytes = open(
"example.tar.gz", "rb"
).read() # Those bytes will come from a decrypt function
input_io = BytesIO(tarbytes)
output_io = _update_tar(input_io, "new_file.txt", "gibberish")
with open("example.tar", "wb") as file: # Those bytes will go to an encrypt func
file.write(output_io.read())
$ echo "Just a simple new file" > new_file.txt
$ ls -l
-rw-r--r-- 1 myuser myuser 3595 Jun 3 23:10 archive.pem
-rw-r--r-- 1 myuser myuser 3059 Jun 4 09:08 example.tar.gz
-rw-r--r-- 1 myuser myuser 50 Jun 3 23:19 gibberish
-rw-r--r-- 1 myuser myuser 23 Jun 4 09:45 new_file.txt
-rw-r--r-- 1 myuser myuser 1024 Jun 3 13:07 some_file.log
-rw-r--r-- 1 myuser myuser 813 Jun 4 09:46 updatetar.py
$ python updatetar.py
Read archive.pem from archive.
Add archive.pem to the new archive!
Read gibberish from archive.
Read some_file.log from archive.
Add some_file.log to the new archive!
$ ls -l
-rw-r--r-- 1 myuser myuser 3595 Jun 3 23:10 archive.pem
-rw-r--r-- 1 myuser myuser 10240 Jun 4 09:46 example.tar
-rw-r--r-- 1 myuser myuser 3059 Jun 4 09:08 example.tar.gz
-rw-r--r-- 1 myuser myuser 50 Jun 3 23:19 gibberish
-rw-r--r-- 1 myuser myuser 23 Jun 4 09:45 new_file.txt
-rw-r--r-- 1 myuser myuser 1024 Jun 3 13:07 some_file.log
-rw-r--r-- 1 myuser myuser 813 Jun 4 09:46 updatetar.py
结果是一样的。正在生成此10K文件
我正在Linux机器上使用Python 3.8.3
谁能帮我找到用Python更新内存中tar文件的正确方法
目前没有回答
相关问题 更多 >
编程相关推荐