2011-02-07 5 views
27

하나의 폴더에 하위 폴더가 들어있는 .zip 파일을 모두 추출하려고합니다. 하위 폴더의 모든 파일을 원본 구조를 유지하지 않고 하나의 폴더에만 추출합니다. 지금은 모두 압축을 풀고 파일을 폴더로 옮긴 다음 이전 하위 폴더를 제거합니다. 같은 이름을 가진 파일은 너무 큽니다.python ZipFile을 사용하여 구조를 유지하지 않고 zip에서 파일의 압축을 풉니 다?

파일을 쓰기 전에 할 수 있습니까?

my_dir/file1.txt 
my_dir/file2.txt 
my_dir/file3.txt 
my_dir/file4.txt 

가이 코드에 무엇을 추가 할 수 있습니다 :이 whish 끝에

my_zip/file1.txt 
my_zip/dir1/file2.txt 
my_zip/dir1/dir2/file3.txt 
my_zip/dir3/file4.txt 

: 여기

는 예를 들어 구조?

KeyError: "There is no item named 'file2.txt' in the archive" 

답변

41

는, f를 추출 ilename을 복사하여 대상 파일에 복사합니다 (서브 디렉토리를 돌 보지 않고 ZipFile.extract이 작동하는 방식입니다).

import os 
import shutil 
import zipfile 

my_dir = r"D:\Download" 
my_zip = r"D:\Download\my_file.zip" 

with zipfile.ZipFile(my_zip) as zip_file: 
    for member in zip_file.namelist(): 
     filename = os.path.basename(member) 
     # skip directories 
     if not filename: 
      continue 

     # copy file (taken from zipfile's extract) 
     source = zip_file.open(member) 
     target = file(os.path.join(my_dir, filename), "wb") 
     with source, target: 
      shutil.copyfileobj(source, target) 
+0

고맙습니다. 작동합니다. – Thammas

7

그냥 대신, 자신을 메모리에 바이트의 압축 파일 이름을 계산하고, 거기에 쓰기 : 나는 파일을 zip_file.namelist()에서 경로 이름을 바꾸면

import zipfile 
my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

zip_file = zipfile.ZipFile(my_zip, 'r') 
for files in zip_file.namelist(): 
    zip_file.extract(files, my_dir) 
zip_file.close() 

,이 오류가 라이브러리를 댄다 그것을 - -mostly, 바로이 방법을 ") (추출물"대신 ") (읽기"사용

이 우편 아카이브의 구성원의 파일 핸들을 엽니 다
import zipfile 
import os 

my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

zip_file = zipfile.ZipFile(my_zip, 'r') 
for files in zip_file.namelist(): 
    data = zip_file.read(files, my_dir) 
    # I am almost shure zip represents directory separator 
    # char as "/" regardless of OS, but I don't have DOS or Windos here to test it 
    myfile_path = os.path.join(my_dir, files.split("/")[-1]) 
    myfile = open(myfile_path, "wb") 
    myfile.write(data) 
    myfile.close() 
zip_file.close() 
+0

감사합니다. 나는 예외를 추가하여 myfile_path에있는 디렉토리 \를 피하고 파일 만 보관해야합니다. – Thammas

2

ZipFile.infolist()을 반복 할 수 있습니다. 반환 된 ZipInfo 개체에서 filename을 조작하여 디렉터리 부분을 제거한 다음 마지막으로 지정된 디렉터리로 추출 할 수 있습니다.

import glob 
import zipfile 
import shutil 
import os 

my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

with zipfile.ZipFile(my_zip) as zip: 
    for zip_info in zip.infolist(): 
     if zip_info.filename[-1] == '/': 
      continue 
     zip_info.filename = os.path.basename(zip_info.filename) 
     zip.extract(zip_info, my_dir) 
관련 문제