ZIP은 압축과 보관(아카이빙)을 위해 가장 널리 사용되는 파일 형식 중 하나입니다. MS-DOS 시절부터 사용되어 왔으며, 유명한 PKZIP 프로그램에서도 이 형식을 채택했습니다.
Python 표준 라이브러리의 zipfile 모듈은 ZIP 아카이브를 생성하고, 압축을 해제하며, 읽고 쓰는 작업을 손쉽게 처리할 수 있는 클래스들을 제공합니다. 이 글에서는 zipfile 모듈의 핵심 기능과 주요 메서드를 예제 코드와 함께 살펴보겠습니다.
ZipFile() 객체 생성하기
ZipFile() 함수는 파일 경로 문자열 또는 내장 open() 함수로 생성한 파일 객체를 받아 ZipFile 객체를 반환합니다. 두 번째 매개변수인 mode는 파일을 여는 방식을 지정하며, 기본값은 'r'(읽기 모드)입니다. 그 외에 'w'(쓰기 모드)나 'a'(추가 모드)를 지정할 수 있습니다.
기본적으로 ZIP 아카이브는 압축되지 않은 상태로 생성됩니다. 압축 알고리즘을 지정하려면 compression 매개변수에 다음 상수 중 하나를 할당해야 합니다.
| zipfile.ZIP_STORED | 압축하지 않고 저장합니다. |
| zipfile.ZIP_DEFLATED | 일반적인 ZIP 압축 방식입니다. zlib 모듈이 필요합니다. |
| zipfile.ZIP_BZIP2 | BZIP2 압축 방식입니다. bz2 모듈이 필요합니다. |
| zipfile.ZIP_LZMA | LZMA 압축 방식입니다. lzma 모듈이 필요합니다. |
write(): 아카이브에 파일 추가하기
write() 메서드는 ZipFile 객체가 나타내는 아카이브에 파일을 추가합니다.
>>> import zipfile
>>> newzip = zipfile.ZipFile('newdir/newzip.zip', 'w')
>>> newzip.write('zen.txt')
>>> newzip.close()이미 존재하는 아카이브에 파일을 추가하려면 추가 모드('a')로 열면 됩니다.
>>> newzip = zipfile.ZipFile('newdir/newzip.zip', 'a')
>>> newzip.write('zen.txt')
>>> newzip.close()read(): 아카이브 내 파일 읽기
read() 메서드는 아카이브 안의 특정 파일 데이터를 읽어옵니다.
>>> newzip = zipfile.ZipFile('newdir/newzip.zip', 'r')
>>> data = newzip.read('json.txt')
>>> data
b'["Rakesh", {"marks": [50, 60, 70]}]'printdir(): 아카이브 목록 출력하기
printdir() 메서드는 주어진 아카이브에 포함된 모든 파일의 목록을 출력합니다.
>>> newzip.printdir() File Name Modified Size json.txt 2018-11-2717:04:40 35 zen.txt 2018-11-2523:13:44 878
extract(): 특정 파일 압축 해제하기
extract() 메서드는 아카이브에서 지정한 파일 하나를 추출합니다. 기본적으로 현재 디렉터리에 저장되며, 두 번째 매개변수로 대상 경로를 지정할 수도 있습니다.
>>> newzip.extract('json.txt', 'newdir')
'newdir\\json.txt'extractall(): 전체 파일 압축 해제하기
extractall() 메서드는 아카이브의 모든 파일을 기본적으로 현재 디렉터리에 추출합니다. 필요하다면 매개변수로 다른 디렉터리를 지정할 수 있습니다.
>>> newzip.extractall('newdir')getinfo(): 파일 메타데이터 조회하기
getinfo() 메서드는 지정한 파일에 해당하는 ZipInfo 객체를 반환합니다. 이 객체에는 파일 이름, 크기, 수정 날짜 등 다양한 메타데이터가 담겨 있습니다.
다음 코드는 아카이브에서 'zen.txt'의 ZipInfo 객체를 얻어 파일 이름, 크기, 날짜·시간 정보를 확인합니다.
>>> inf = newzip.getinfo('zen.txt')
>>> inf.filename, inf.file_size, inf.date_time
('zen.txt', 878, (2018, 11, 25, 23, 13, 45))infolist(): 모든 파일 정보 한 번에 가져오기
infolist() 메서드는 아카이브 내 모든 파일에 대한 ZipInfo 객체 리스트를 반환합니다.
>>> newzip.infolist() [<ZipInfo filename = 'json.txt' filemode='-rw-rw-rw-' file_size=35>, <ZipInfo filename = 'zen.txt' filemode='-rw-rw-rw-' file_size=878>]
앞서 언급했듯이, ZIP 아카이브를 생성할 때 적용할 압축 알고리즘은 compression 매개변수로 지정합니다. 다음 코드에서는 ZIP_DEFLATED 상수를 사용해 zlib 압축으로 아카이브를 만듭니다.
>>> zipobj = zipfile.ZipFile('txtzip.zip', mode='w', compression=zipfile.ZIP_DEFLATED)
>>> files = glob.glob("*.txt")
>>> for file in files:
zipobj.write(file)
>>> zipobj.close()namelist(): 파일 이름 목록 가져오기
ZipFile 객체의 namelist() 메서드는 아카이브에 포함된 모든 파일 이름의 리스트를 반환합니다.
>>> zipobj = zipfile.ZipFile('txtzip.zip', mode='r')
>>> zipobj.namelist()
['a!.txt', 'data().txt', 'dict.txt', 'json.txt', 'LICENSE.txt', 'lines.txt', 'msg.txt', 'NEWS.txt', 'test.txt/', 'zen.txt', 'zen1.txt', 'zenbak.txt']setpassword(): 비밀번호 설정하기
setpassword() 메서드는 아카이브를 추출할 때 필요한 비밀번호를 설정합니다. 암호로 보호된 ZIP 파일을 다룰 때 유용하게 사용됩니다.
PyZipFile(): 파이썬 모듈 아카이브 만들기
zipfile 모듈의 PyZipFile() 함수는 PyZipFile 객체를 반환합니다. 이 객체는 .py 확장자를 가진 파일들을 담은 아카이브를 구성할 수 있으며, 해당 아카이브를 sys.path 환경 변수에 추가하면 zipimport 모듈을 통해 모듈처럼 임포트할 수 있습니다.
writepy() 메서드는 .py 파일을 컴파일하여 대응하는 .pyc 파일로 만든 뒤 아카이브에 추가합니다.
files = glob.glob("*.py")
>>> pyzipobj = zipfile.PyZipFile('pyfiles/pyzip.zip', mode='w', compression=zipfile.ZIP_LZMA)
>>> for file in files:
pyzipobj.writepy(file)
>>> pyzipobj.close()마무리
지금까지 Python zipfile 모듈의 핵심 클래스와 함수들을 살펴보았습니다. ZipFile 객체의 다양한 메서드를 활용하면 파일 압축, 보관, 추출 작업을 별도의 외부 도구 없이 코드만으로 효율적으로 처리할 수 있습니다.