2012-08-13 6 views
8

파이썬에서 중첩 된 zip 파일을 압축 해제 할 방법을 찾고 있습니다.파이썬에서 중첩 된 zip 파일 압축 해제

  • 폴더
    • ZipfileA.zip
      • ZipfileA1.zip
      • ZipfileA2.zip
    • ZipfileB 예를 들어, 다음과 같은 구조 (편의를 위해 가상 이름) 고려 .zip
      • ZipfileB1.zip
      • ZipfileB2.zip

... 등. 두 번째 우편 번호 내에있는 텍스트 파일에 액세스하려고합니다. 전단 숫자가 컴퓨터를 부수기 때문에 모든 것을 추출하고 싶지는 않습니다 (첫 번째 레이어에는 수백 개의 zip이 있고 두 번째 레이어에는 거의 10,000 개의 zip이 있음).

저는 'zipfile'모듈을 가지고 놀았습니다. 저는 첫 번째 수준의 zip 파일을 열 수 있습니다. 예컨대는 :

zipfile_obj = zipfile.ZipFile("/Folder/ZipfileA.zip") 
next_layer_zip = zipfile_obj.open("ZipfileA1.zip") 

그러나, 이것은 "ZipExtFile"예 (없는 파일이나 ZipFile를 인스턴스)를 반환 - 그리고 그때에 가서이 특정 데이터 형식을 열 수 없습니다. 나는이 작업을 수행 할 수 :

data = next_layer_zip.open(data.txt) 

나는 그러나 함께이 zip 파일 파일을 "읽기"수

next_layer_zip.read() 

을하지만이 완전히 쓸모입니다! (즉, 압축 된 데이터/goobledigook 만 읽을 수 있음).

사람은 (ZipFile.extract를 사용없이) 내가 이것에 대해 갈 수있는 방법에 대한 아이디어가 있습니까?

내가 정확히 무엇을 하려는지 보이는 http://pypi.python.org/pypi/zip_open/ -이 것이 나에게 적합하다고 보지 않습니다. (계속 "[Errno 2] No such file or directory :"모듈을 사용하여 처리하려고하는 파일).

어떤 아이디어라도 높이 평가할 것입니다 !! 미리 감사드립니다.

답변

8

불행히도 압축 파일을 압축하면 압축 파일에 무작위로 액세스해야하며, ZipFile 방법 (DEFLATE 알고리즘 자체는 말할 것도 없습니다) 만 스트림을 제공합니다. 따라서 압축하지 않고 중첩 된 zip 파일을 압축 해제하는 것은 불가능합니다.

5

ZipFile에는 파일과 유사한 개체가 필요하므로 StringIO를 사용하여 중첩 된 zip에서 읽은 데이터를 해당 개체로 바꿀 수 있습니다. 주의 할 점은 내부 (여전히 압축 된) 내부 지퍼를 메모리에로드한다는 것입니다.

with zipfile.ZipFile('foo.zip') as z: 
    with z.open('nested.zip') as z2: 
     z2_filedata = cStringIO.StringIO(z2.read()) 
     with zipfile.ZipFile(z2_filedata) as nested_zip: 
      print nested_zip.open('data.txt').read() 
4

다음은 내가 생각해 낸 기능입니다.원래 zip 파일 중첩 된 압축 파일 (중첩의 모든 수준)을 추출하고 정리하는 기능을 찾는 분들을 위해

echo hello world > hi.txt 
zip wrap1.zip hi.txt 
zip wrap2.zip wrap1.zip 
zip wrap3.zip wrap2.zip 

print extract_nested_zipfile('/Users/mattfaus/dev/dev-git/wrap1.zip').open('hi.txt').read() 
print extract_nested_zipfile('/Users/mattfaus/dev/dev-git/wrap2.zip/wrap1.zip').open('hi.txt').read() 
print extract_nested_zipfile('/Users/mattfaus/dev/dev-git/wrap3.zip/wrap2.zip/wrap1.zip').open('hi.txt').read() 
+0

당신을 위해 3.3을 사용하면 시간을 절약 할 수 있습니다.'TypeError : 예상되는 문자열 인수'memory_zip.write (parent_zip.open (child_zip_path) .read())'행과 관련된 'bytes' 해결 방법 – user25064

0

:

import zipfile, re, os 

def extract_nested_zip(zippedFile, toFolder): 
    """ Unzip a zip file and its contents, including nested zip files 
     Delete the zip file(s) after extraction 
    """ 
    with zipfile.ZipFile(zippedFile, 'r') as zfile: 
     zfile.extractall(path=toFolder) 
    os.remove(zippedFile) 
    for root, dirs, files in os.walk(toFolder): 
     for filename in files: 
      if re.search(r'\.zip$', filename): 
       fileSpec = os.path.join(root, filename) 
       extract_nested_zip(fileSpec, root) 
을 여기

def extract_nested_zipfile(path, parent_zip=None): 
    """Returns a ZipFile specified by path, even if the path contains 
    intermediary ZipFiles. For example, /root/gparent.zip/parent.zip/child.zip 
    will return a ZipFile that represents child.zip 
    """ 

    def extract_inner_zipfile(parent_zip, child_zip_path): 
     """Returns a ZipFile specified by child_zip_path that exists inside 
     parent_zip. 
     """ 
     memory_zip = StringIO() 
     memory_zip.write(parent_zip.open(child_zip_path).read()) 
     return zipfile.ZipFile(memory_zip) 

    if ('.zip' + os.sep) in path: 
     (parent_zip_path, child_zip_path) = os.path.relpath(path).split(
      '.zip' + os.sep, 1) 
     parent_zip_path += '.zip' 

     if not parent_zip: 
      # This is the top-level, so read from disk 
      parent_zip = zipfile.ZipFile(parent_zip_path) 
     else: 
      # We're already in a zip, so pull it out and recurse 
      parent_zip = extract_inner_zipfile(parent_zip, parent_zip_path) 

     return extract_nested_zipfile(child_zip_path, parent_zip) 
    else: 
     if parent_zip: 
      return extract_inner_zipfile(parent_zip, path) 
     else: 
      # If there is no nesting, it's easy! 
      return zipfile.ZipFile(path) 

내가 그것을 테스트 방법