메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

파이썬을 사용해 한글 파일명을 포함한 ZIP 파일 압축 해제

한빛미디어

|

2016-09-28

|

by 이지호

41,218

ZIP 압축과 인터넷

 

인터넷을 사용하는 인구가 늘면서 많은 사람이 대용량의 파일을 주고 받기 시작했다. 인터넷 이전의 지역적인 통신망이었던 PC 통신에서도 여러 개의 파일을 주고 받기 위해 다양한 압축 유틸리티가 사용되었다. 많은 압축 유틸리티 중 ARJ, RAR, ZIP이 가장 많은 인기를 끌고 있었다.

 

ZIP 압축은 인터넷이 확산되면서 많은 인기를 끌게 되었는데 여기에는 ZIP 압축 알고리즘의 라이센스가 BSD 라이센스에 가까운 라이센스였기 때문이었다.

 

ZIP 압축과 다국어

 

우리가 일상 생활에서 사용하는 언어는 한국어고 이를 표기하는 글자는 한글이다. 이처럼 한글을 컴퓨터에서 사용하기 위해서는 한글을 컴퓨터가 알아들을 수 있도록 변환 작업이 필요하다. 이 변환 작업을 인코딩이라고 부른다.

 

ZIP 압축은 1990년대 초에 만들어지고 이때만 하더라도 컴퓨터에 다국어 이슈가 없었다. 그러나 2000년대에 접어들면서 국가별로 상이한 인코딩 형식에 맞춰 생성된 파일 이름은 다양한 인코딩을 사용하는 운영체제에서 오류를 발생시키기 시작했다.

 

ZIP 압축도 다국어 이슈에서 자유롭지 못해 지역적 인코딩(한글을 예로 들면 EUC-KR)된 파일명으로 구성된 파일이 압축파일에 있으면 압축파일을 해제할 때 필연적으로 한글로 구성된 파일 이름은 깨진다.

 

윈도우와 윈도우가 아닌 것들

 

정말 다행스럽게도 마이크로소프트 윈도우에서 압축된 ZIP 파일에 한글 이름으로 구성된 파일이 있어도 압축 파일을 같은 운영체제인 마이크로소프트 윈도우에서 해제하면 파일 이름은 깨지지 않는다.

 

그러나 윈도우에서 압축한 파일이 다른 운영체제인 Linux, Mac OS, BSD 등에서 해제하게 되면 영문자와 숫자로 구성된 파일 이름이 아닌 경우 앞에서 이야기한것처럼 파일 이름이 깨지게 된다.

 

여러분이 Debian/Ubuntu 리눅스에서 X 윈도우를 사용한다면 arkzip 이란 유틸리티를 사용해 한글 이름 포함된 압축 파일을 해제할 수 있다.

 

그러나 문제는 필자와 같이 간혹 X 윈도우를 사용하지 않고 Mac OS를 사용하는 유저의 경우엔 이 문제를 해결하기가 쉽지 않다.

 

파이썬를 사용해 ZIP 파일 해제하기

 

여러분이 앞의 상황에 처해 있다면 파이썬을 사용해 이 문제를 쉽게 해결할 수 있다. 대부분의 리눅스와 Mac OS는 파이썬을 기본적으로 제공하기 때문에 파이썬을 설치하기 위해 고생하지 않아도 된다.

 

다음은 한글로 구성된 파일 이름이 있는 ZIP 압축을 해제하는 파이썬 스크립트다.

 

import zipfile

import os

import sys

 

def unzip(source_file, dest_path):

    with zipfile.ZipFile(source_file, 'r') as zf:

        zipInfo = zf.infolist()

 

        for member in zipInfo:

            member.filename = member.filename.decode("euc-kr").encode("utf-8")

            zf.extract(member)

 

if __name__ == "__main__":

    unzip(sys.argv[1], '')

 

 

파이썬은 기본 지원 모듈로 ZIP 압축과 해제를 할 수 있는 zipfile 모듈을 제공한다.

 

이 모듈을 통해 압축을 해제하는 순서는 다음과 같다.

  1. ZipFile 클래스에 압축을 해제할 파일과 읽기 전용 모드를 제공해 ZipFile 객체를 with 문을 사용해 생성한다.
  2. ZipFile 객체의 infolist 메서드를 사용해 ZIP 파일에 압축되어 있는 파일 목록(디렉터리도 파일로 취급)을 가져온다(변수명 예, zipInfo)
  3. for 문을 사용해 zipInfo 변수를 순회한다.
  4. zipInfo 변수안에 있는 개별의 객체는 ZIpInfo 객체로 이 안에서 filename 속성의 값을 euc-kr로 해석한후 utf-8로 다시 인코딩한 값으로 덮어쓴다.
  5. ZipFile 객체의 extract 메서드에 ZipInfo 객체(for 문 안에선 member 변수)를 인자로 제공한다.

앞의 스크립트를 임의의 이름 (예, unzip2.py)으로 저장해서 /usr/local/bin에 옮겨두고 압축을 해제하기 위해 다음의 명령을 사용하면 쉽게 사용할 수 있다.

 

$ python /usr/local/bin/unzip2.py <압축파일명>

 

이 스크립트는 운영체제에서 설치되는 unzip 프로그램과 달리 압축 파일이 해제되는 모습은 보여주지 않는다. 이에 따라 이 부분은 여러분이 직접 구현해보길 바란다.

 

마침

 

인터넷 상에 있는 많은 문서가 이 문제를 해결하기 위해 unzip 명령어 -O 옵션을 사용하는 것으로 되어 있으나 필자가 사용중인 OSX와 데비안 리눅스에서는 unzip 명령어에 -O 옵션이 제공되지 않았다. ZIP 파일 압축 해제에 이름이 깨지는 문제가 발생하면 이 문서를 참고하면 여러분에게 도움이 될것이다.

 

더불어 ZIP 파일이 인터넷에서 관용적으로 사용되고 있지만 필자는 7zip 을 사용하는 것을 권장한다. 7zip은 파일 이름등의 문제에 있어 다국어 처리가 잘되어 있다.

댓글 입력
자료실

최근 본 상품0