[英]How can I programmatically create a tar archive of nested directories and files solely from Python strings and without temporary files?
我想用Python创建一个带有分层目录结构的tar存档,使用字符串作为文件内容。 我已经阅读了这个问题 ,它显示了一种将字符串添加为文件的方法,但不是作为目录。 如何在不实际制作目录的情况下动态添加目录到tar存档?
就像是:
archive.tgz:
file1.txt
file2.txt
dir1/
file3.txt
dir2/
file4.txt
扩展链接问题中给出的示例,您可以按如下方式进行:
import tarfile
import StringIO
import time
tar = tarfile.TarFile("test.tar", "w")
string = StringIO.StringIO()
string.write("hello")
string.seek(0)
info = tarfile.TarInfo(name='dir')
info.type = tarfile.DIRTYPE
info.mode = 0755
info.mtime = time.time()
tar.addfile(tarinfo=info)
info = tarfile.TarInfo(name='dir/foo')
info.size=len(string.buf)
info.mtime = time.time()
tar.addfile(tarinfo=info, fileobj=string)
tar.close()
请注意mode
属性,因为默认值可能不包含更改为它并获取其内容所需的目录所有者的执行权限。
看看tar文件格式似乎可行。 进入每个子目录的文件获取相对路径名(例如dir1/file3.txt
)作为其名称。
唯一的技巧是你必须在进入它的文件之前定义每个目录( tar
不会动态创建必要的子目录)。 有一个特殊标志可用于将tarfile条目标识为目录,但出于传统目的, tar
还接受名称以/
作为代表目录结尾的文件条目,因此您应该能够将dir1/
添加为文件使用相同的技术从零长度字符串。
稍微修改了有用的接受答案,以便它可以与python 3以及python 2一起使用(并且将OP的示例更接近):
from io import BytesIO
import tarfile
import time
# create and open empty tar file
tar = tarfile.open("test.tgz", "w:gz")
# Add a file
file1_contents = BytesIO("hello 1".encode())
finfo1 = tarfile.TarInfo(name='file1.txt')
finfo1.size = len(file1_contents.getvalue())
finfo1.mtime = time.time()
tar.addfile(tarinfo=finfo1, fileobj=file1_contents)
# create directory in the tar file
dinfo = tarfile.TarInfo(name='dir')
dinfo.type = tarfile.DIRTYPE
dinfo.mode = 0o755
dinfo.mtime = time.time()
tar.addfile(tarinfo=dinfo)
# add a file to the new directory in the tar file
file2_contents = BytesIO("hello 2".encode())
finfo2 = tarfile.TarInfo(name='dir/file2.txt')
finfo2.size = len(file2_contents.getvalue())
finfo2.mtime = time.time()
tar.addfile(tarinfo=finfo2, fileobj=file2_contents)
tar.close()
特别是,我更新了PEP 3127之后的八进制语法- 整数文字支持和语法 , BytesIO from io
切换到BytesIO from io
,使用getvalue
而不是buf
,并使用open
而不是TarFile
来显示压缩输出,如示例所示。 (上下文处理程序用法( with ... as tar:
:)也可以在python2和python3中使用,但剪切和粘贴不能用于我的python2 repl,所以我没有切换它。)在python 2.7.15上测试+和python 3.7.3。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.