python write string directly to tarfile

后端 未结 7 1275
-上瘾入骨i
-上瘾入骨i 2020-12-08 13:28

Is there a way to write a string directly to a tarfile? From http://docs.python.org/library/tarfile.html it looks like only files already written to the file system can be a

相关标签:
7条回答
  • 2020-12-08 13:43

    You have to use TarInfo objects and the addfile method instead of the usual add method:

    from StringIO import StringIO
    from tarfile import open, TarInfo
    
    s = "Hello World!"
    ti = TarInfo("test.txt")
    ti.size = len(s)
    
    tf = open("testtar.tar", "w")
    tf.addfile(ti, StringIO(s))
    
    0 讨论(0)
  • 2020-12-08 13:46

    I would say it's possible, by playing with TarInfo e TarFile.addfile passing a StringIO as a fileobject.

    Very rough, but works

    import tarfile
    import StringIO
    
    tar = tarfile.TarFile("test.tar","w")
    
    string = StringIO.StringIO()
    string.write("hello")
    string.seek(0)
    info = tarfile.TarInfo(name="foo")
    info.size=len(string.buf)
    tar.addfile(tarinfo=info, fileobj=string)
    
    tar.close()
    
    0 讨论(0)
  • 2020-12-08 13:48

    In my case I wanted to read from an existing tar file, append some data to the contents, and write it to a new file. Something like:

    for ti in tar_in:
        buf_in = tar.extractfile(ti)
        buf_out = io.BytesIO()
        size = buf_out.write(buf_in.read())
        size += buf_out.write(other data)
        buf_out.seek(0)
        ti.size = size
        tar_out.addfile(ti, fileobj=buf_out)
    

    Extra code is needed for handling directories and links.

    0 讨论(0)
  • 2020-12-08 13:54

    As Stefano pointed out, you can use TarFile.addfile and StringIO.

    import tarfile, StringIO
    
    data = 'hello, world!'
    
    tarinfo = tarfile.TarInfo('test.txt')
    tarinfo.size = len(data)
    
    tar = tarfile.open('test.tar', 'a')
    tar.addfile(tarinfo, StringIO.StringIO(data))
    tar.close()
    

    You'll probably want to fill other fields of tarinfo (e.g. mtime, uname etc.) as well.

    0 讨论(0)
  • 2020-12-08 13:59

    I found this looking how to serve in Django a just created in memory .tgz archive, may be somebody else will find my code usefull:

    import tarfile
    from io import BytesIO
    
    
    def serve_file(request):
        out = BytesIO()
        tar = tarfile.open(mode = "w:gz", fileobj = out)
        data = 'lala'.encode('utf-8')
        file = BytesIO(data)
        info = tarfile.TarInfo(name="1.txt")
        info.size = len(data)
        tar.addfile(tarinfo=info, fileobj=file)
        tar.close()
    
        response = HttpResponse(out.getvalue(), content_type='application/tgz')
        response['Content-Disposition'] = 'attachment; filename=myfile.tgz'
        return response
    
    0 讨论(0)
  • 2020-12-08 14:02

    Just for the record:
    StringIO objects have a .len property.
    No need to seek(0) and do len(foo.buf)
    No need to keep the entire string around to do len() on, or God forbid, do the accounting yourself.

    ( Maybe it did not at the time the OP was written. )

    0 讨论(0)
提交回复
热议问题