:: python

python :: 파이썬 zipfile 로 파일 압축하기(하위폴더 포함/미포함) & 압축 해제하기

토람이 2021. 6. 15. 13:02

파이썬에서 파일 압축 & 압축 해제는 zipfile 라이브러리를 사용한다.

 

C:\test
   └ directory1
       └ file4.txt
   └ file1.txt
   └ file2.txt
   └ file3.txt

 

위 구조에서 C:\test 아래에 있는 txt 파일들을 압축해보기로 한다.

 

이 때,

test 폴더 안의 txt 파일만 압축하려면 os.listdir 을,

test 폴더 내 모든 하위폴더 아래에 있는 txt 파일을 다 압축하려면 os.walk 를 사용한다.

 

* 참고: https://toramko.tistory.com/2

 

python * os.listdir과 os.walk (파이썬 특정 경로 내 디렉토리와 파일 검색)

다음과 같이 폴더와 파일을 생성해두었다. C:\test  └ directory1  └ file4.txt  └ file1.txt  └ file2.txt  └ file3.txt 1. os.listdir os.listdir(path) 특정 경로 내에 존재하는 폴더(디렉토리)와 파..

toramko.tistory.com

 

1. test 폴더 아래 파일만 압축 (file1~3.txt)

import zipfile

file_path = 'C:\\test'

zip_file = zipfile.ZipFile(file_path + "\\output.zip", "w")  # "w": write 모드
for file in os.listdir(file_path):
    if file.endswith('.txt'):
        zip_file.write(os.path.join(file_path, file), compress_type=zipfile.ZIP_DEFLATED)

zip_file.close()

 

- os.path.join(file_path, file): file_path 와 file 을 하나의 경로로 묶어준다.
  (C:\test, file1.txt => C:\test\file1.txt)

- compress_type: 압축 포맷 형식. ZIP_DEFLATED 가 일반적으로 쓰인다.

- 다 작성한 zip file 은 꼭 닫아줄 것! (.close())

 

위 내용을 실행하면 C:\test\output.zip 에 file1.txt, file2.txt, file3.txt 이 압축된다.

 

 

2. test 폴더 아래 모든 하위폴더 안의 파일 압축 (file1~4.txt)

import zipfile

file_path = 'C:\\test'

zip_file = zipfile.ZipFile(file_path + "\\output.zip", "w")
for (path, dir, files) in os.walk(file_path):
    for file in files:
        if file.endswith('.txt'):
            zip_file.write(os.path.join(path, file), compress_type=zipfile.ZIP_DEFLATED)

zip_file.close()

 

위 내용을 실행하면 file1~3.txt + directory1/file4.txt 까지 모두 압축된다.

 

 

3. 압축 파일 해제하기

file_path = 'C:\\result'

output_unzip = zipfile.ZipFile("C:\\test\\output.zip", "r")  # "r": read 모드
output_unzip.extractall(file_path)
output_unzip.close()

 

좀 전에 압축했던 txt 파일들을 C:\result 에 풀어보았다.

 

그런데 실행해보니 이상하게 C:\result 아래에 txt 파일은 없고 'test' 폴더가 있다.

os.walk 이 "C:\" 부터의 경로를 반환하는데,

zipfile 이 파일 압축 시 "C:\" 부터 시작하는 이 경로 정보를 포함해서 압축하기 때문이라 한다.

 

이런 일을 방지하려면 다음과 같이 작성하면 된다.

 

 

4. 상대경로를 활용하여 압축하기

import zipfile
import os  # os 모듈 import

file_path = 'C:\\test'
owd = os.getcwd()  # 현재 working directory 를 기록해둔다
os.chdir(file_path)  # 압축 파일 생성할 폴더로 working directory 를 이동시킨다

zip_file = zipfile.ZipFile("output.zip", "w")
for (path, dir, files) in os.walk(file_path):
    for file in files:
        if file.endswith('.txt'):
            # 상대경로를 활용하여 압축한다. (os.path.relpath)
            zip_file.write(os.path.join(os.path.relpath(path, file_path), file), compress_type=zipfile.ZIP_DEFLATED)

zip_file.close()
os.chdir(owd)  # 원래의 working directory 로 되돌린다

 

- os.getcwd(): 현재 working directory

- os.chdir(file_path): file_path 경로로 이동

- os.path.relpath(A, B): B 경로를 기준으로 A 경로의 상대경로 반환
  (C:\test\directory1, C:\test => directory1)

 

 

주석을 달아둔 내용이 추가된 내용이다.

위 내용으로 돌린 후 압축 해제하니

정상적인 구조로 파일들이 풀렸다.

300x250