2009-04-11 38 views

Trả lời

28

Tôi có thể nói rằng có thể, bằng cách chơi với TarInfo e TarFile.addfile chuyển qua một StringIO dưới dạng tệp tin.

Rất thô, nhưng hoạt động

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() 
+1

Bạn chỉ có thể nói StringIO.StringIO ("hello") để thay thế văn bản và tìm kiếm. – misha

+0

là thủ tục tương tự như đối tượng python3 và byteIO? – proteneer

+2

@proteneer: Tôi tin vào python 3 phương pháp tìm kiếm cung cấp cho bạn một chiều dài nhị phân, trong khi nó sử dụng nội bộ chuỗi '' 'len()' '' hàm, do đó, '' 'tarfile.copyfileobj''' chức năng sẽ thất bại với '' 'nâng cao OSError (" kết thúc của tập tin đạt được ")' '' – luckydonald

14

Như Stefano chỉ ra, bạn có thể sử dụng TarFile.addfileStringIO.

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() 

Có thể bạn sẽ muốn để điền vào các lĩnh vực khác của tarinfo (ví dụ mtime, uname vv) cũng.

+0

là "Như Stefano chỉ ra" một chỉnh sửa? Nếu không, tôi không thấy những gì bạn đang làm khác nhau. Cảm ơn phản ứng tất cả như nhau. – gatoatigrado

+0

Tôi nghĩ rằng Stefano đã không có bất kỳ mã đăng tại thời điểm tôi đã viết phản ứng của tôi, ông chỉ lưu ý rằng TarFile.addfile và StringIO có thể được sử dụng. Mặc dù bộ nhớ của tôi hơi mờ. – avakar

+0

FWIW, vâng, @ thông tin chi tiết của Stefano đã được thêm vào [sửa] (http://stackoverflow.com/posts/740839/revisions) sau khi bạn đã viết. Câu trả lời khác nói cùng một điều cũng đến gần như cùng một lúc. – mattdm

2

Bạn phải sử dụng đối tượng TarInfo và phương pháp addfile thay vì phương thức add thông thường:

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)) 
2

Trong trường hợp của tôi, tôi muốn đọc từ một file tar hiện có, thêm một số dữ liệu để các nội dung, và viết nó vào một tập tin mới. Một cái gì đó như:

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) 

Cần thêm mã để xử lý các thư mục và liên kết.

2

Chỉ để lưu nội dung:
Đối tượng StringIO có thuộc tính .len.
Không cần phải tìm kiếm (0) và làm len (foo.buf)
Không cần phải giữ toàn bộ chuỗi xung quanh để làm len() trên, hoặc Thiên Chúa cấm, làm kế toán cho mình.

(Có lẽ nó đã không tại thời điểm OP đã được viết.)

6

Tôi thấy điều này tìm cách để phục vụ trong Django một vừa tạo trong bộ nhớ lưu trữ .tgz, có thể ai đó sẽ tìm thấy hữu ích mã của tôi:

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 
Các vấn đề liên quan