2013-06-25 2 views
1

파이썬에서 메모리 내 zip 파일을 만들어 Amazon S3에 업로드하려고합니다. 이 문제와 관련하여 유사한 게시물을 읽었지만, Windows와 Linux (RHEL5)는 열 수 없습니다 (손상되었습니다).메모리 Zip 파일 파이썬 오류

f_redirects = StringIO() 
f_links = StringIO() 
f_metadata = StringIO() 

# Write to the "files" 

zip_file = StringIO() 
zip = zipfile.ZipFile(zip_file, 'a', zipfile.ZIP_DEFLATED, False) 
zip.writestr('redirects.csv', f_redirects.getvalue()) 
zip.writestr('links.csv', f_bad_links.getvalue()) 
zip.writestr('metadata.csv', f_metadata.getvalue()) 

f_redirects.close() 
f_links.close() 
f_metadata.close() 

k = Key(BUCKET) 
k.key = '%s.zip' % base_name 
k.set_metadata('Content-Type', 'application/zip') 
k.set_contents_from_string(zip_file.getvalue()) 
zip.close() 
zip_file.close() 
+0

먼저'.zip' 파일을 로컬에 저장하고 열어서 문제가 S3과 관련이 있는지 여부를 확인해 보셨습니까? – abarnert

답변

5

문제는 당신이 당신이 그것에 close를 호출하기 전에 ZipFile의 내용을 사용하려는 것입니다 : 여기에 내가 실행 해요 코드입니다. the documentation으로

는 말한다 : 당신은 close()를 호출해야합니다 ... 또는 중요한 기록이 기록되지 않습니다

.

가끔은 작동하지만 실제로 닫힌 StringIOgetvalue()을 호출하는 것은 유효하지 않습니다. 다시 말하지만, the docs에서 : StringIO 객체의 close() 방법 전에 언제든지 버퍼의 전체 내용을 포함

돌려 str라고합니다.

마지막으로 Python 3.x를 사용하는 경우 StringIO 대신 BytesIO을 사용하고 싶을 것입니다. 실제로, 2.6 이상을 사용하는 한 2.x에서도 BytesIO을 사용할 수 있습니다. 당신이 with 문 대신 수동으로 close 일에 노력을 사용하고, "상단에 변수를 선언하지 않은 경우


또한, 코드가 잘못되기 훨씬 더 읽기, 더 열심히 할 것 "C-스타일 :

with BytesIO() as zip_file: 
    with zipfile.ZipFile(zip_file, 'a', zipfile.ZIP_DEFLATED, False) as zip: 
     zip.writestr('redirects.csv', f_redirects.getvalue()) 
     zip.writestr('links.csv', f_bad_links.getvalue()) 
     zip.writestr('metadata.csv', f_metadata.getvalue()) 
    zip_contents = zip_file.getvalue() 

k = Key(BUCKET) 
k.key = '%s.zip' % base_name 
k.set_metadata('Content-Type', 'application/zip') 
k.set_contents_from_string(zip_contents) 

파이썬 2.x를 사용, StringIO와 함께 있고 싶어하는 경우 첫 번째 라인을 교체해야하므로,이, 컨텍스트 매니저로 직접 사용할 수 없습니다 다음을 포함합니다 :

with contextlib.closing(StringIO()) as zip_file: 
+0

도움을 주셔서 감사합니다! –