파이썬으로 파일 이름으로 잘못된 문자가있는 파일을 추출하십시오
문제
Python의 ZipFile 모듈을 사용하여 .zip 아카이브를 추출합니다 (이 파일을 http://img.dafont.com/dl/?f=akvaleir 예를 들어.)
f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
print fileinfo.filename
f.extract(fileinfo, '.')
출력 :
Akval�ir_Normal_v2007.ttf
Akval�ir, La police - The Font - Fr - En.pdf
파일 이름에 유효하지 않은 인코딩 된 문자가 있기 때문에 추출 후 두 파일 모두 접근 할 수 없습니다. 문제는 ZipFile 모듈에 출력 파일 이름을 지정할 옵션이 없다는 것입니다.
그러나 "unzip akvaleir.zip"은 파일 이름을 잘 피합니다.
root@host:~# unzip akvaleir.zip
Archive: akvaleir.zip
inflating: AkvalВir_Normal_v2007.ttf
inflating: AkvalВir, La police - The Font - Fr - En.pdf
파이썬 프로그램에서 "Unzip -l akvaleir.zip"의 출력 캡처를 시도 했는데이 두 파일 이름은 다음과 같습니다.
Akval\xd0\x92ir_Normal_v2007.ttf
Akval\xd0\x92ir, La police - The Font - Fr - En.pdf
"unzip -l akvaleir.zip"의 출력을 캡처하지 않고 Unzip 명령이하는 것과 같은 올바른 파일 이름을 어떻게 얻을 수 있습니까?
해결책
대신 extract
방법, 사용 open
예를 들어 원하는 이름 아래에서 디스크에 결과적으로 pseudofile을 저장하고 저장하십시오. shutil.copyfileobj
.
다른 팁
시간이 걸렸지 만 답을 찾았다 고 생각합니다.
나는 그 단어가 akvaléir라고 가정했다. 프랑스어로 페이지 설명을 찾았습니다. 코드 스 니펫을 사용했을 때 문자열이있었습니다.
>>> fileinfo.filename
'Akval\x82ir, La police - The Font - Fr - En.pdf'
>>>
UTF8, Latin-1, CP-1251 또는 CP-1252 인코딩에서는 작동하지 않았습니다. 그런 다음 CP863이 가능한 캐나다 인코딩이라는 것을 알았으므로 아마도 이것은 프랑스 캐나다에서 온 것일 것입니다.
>>> print unicode(fileinfo.filename, "cp863").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>>
그러나 나는 그것을 읽습니다 zip 파일 형식 사양 말한다
ZIP 형식은 일반적으로 IBM 코드 Page 437이라고하는 원래 IBM PC 문자 인코딩 세트 만 역사적으로 지원했습니다.
...
범용 비트 11이 설정되면 Filename 및 주석은 UTF-8 스토리지 사양에 의해 정의 된 문자 인코딩 양식을 사용하여 유니 코드 표준 버전 4.1.0 이상을 지원해야합니다.
테스트를 테스트하면 캐나다 코드 페이지와 동일한 답변을 제공합니다.
>>> print unicode(fileinfo.filename, "cp437").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>>
유니 코드 인코딩 된 zip 파일이없고 알아 내기 위해 하나를 만들지 않으므로 모든 zip 파일에 CP437 인코딩이 있다고 가정합니다.
import shutil
import zipfile
f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
filename = unicode(fileinfo.filename, "cp437")
outputfile = open(filename, "wb")
shutil.copyfileobj(f.open(fileinfo.filename), outputfile)
내 MAC에서
109936 Nov 27 01:46 Akvale??ir_Normal_v2007.ttf
25244 Nov 27 01:46 Akvale??ir, La police - The Font - Fr - En.pdf
어떤 탭에 완성됩니다
ls Akvale\314\201ir
내 파일 브라우저에 멋진 'é'가 나타납니다.
Docker를 사용하여 응용 프로그램을 실행하는 동안 비슷한 문제를 해결했습니다. 이 라인을 dockerfile에 추가하면 모든 것을 수정했습니다.
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
따라서 Docker를 사용하지 않는다면 시도해보고 로컬이 올바르게 생성되어 설정되어 있는지 확인하십시오.