風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

ZIPファイルに日本語ファイル名が含まれる場合の文字化け予防方法(Windows7, CentOS 6)

他のシステムで作成されたZIPファイルを解凍した際に日本語ファイル名が文字化けする不具合への対処法をいくつか。



Windows7 の場合

標準の状態だと、Shift-JIS(CP932)以外でエンコードされていると、文字化けする。

これまでは

無料圧縮・解凍フリーソフト CubeICE - CubeSoft

などを使うことで対処していたが、日本語ファイル名が UTF-8 でエンコードされているものについては、Windows7・Windows Server 2008 R2 用 Hotfix を適用すれば解消される模様。

File names are corrupted after you decompress a .zip file in Windows 7 or in Windows Server 2008 R2

CentOS 6 の場合(unzip)

CentOS 6 系で yum を使ってインストールできる unzip (CentOS 6.6では現在 unzip-6.0-2.el6_6.x86_64) では、日本語ファイル名には未対応のため、エンコードに関わりなく文字化けしてしまう。

【UTF-8 エンコード時】

$ /usr/bin/unzip -l ./AmazonMusicDownload.zip
Archive:  ./AmazonMusicDownload.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
  8381815  10-11-2015 01:53   ?????????????(???????????????)/Cherish you/01 - Cherish you.mp3
  9099388  10-11-2015 01:53   ?????????????+?????????????????/?????????????+????????????????? ??????????????+??+????????+???????????????/01
- Blooming Lily.mp3
  8447415  10-11-2015 01:54   ?????????????+?????????????????/?????????????+????????????????? ??????????????+??+????????+???????????????/03
- ???????????????????????????.mp3
---------                     -------
 25928618                     3 files

【Shift-JIS エンコード時】

$ /usr/bin/unzip -l ./sjis-sample.zip
Archive:  ./sjis-sample.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  10-11-2015 10:59   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/
  9099388  10-11-2015 01:53   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/03 - ?`???X?L?????_???X.mp3
        0  10-11-2015 10:59   ?X?????q??(???????F??)/Cherish you/
  8381815  10-11-2015 01:53   ?X?????q??(???????F??)/Cherish you/01 - Cherish you.mp3
---------                     -------
 25928618                     5 files


そこで、unzip 6.0 Shift-JIS対応版 をインストールすることで対応してみることに。

unzip 6.0 Shift-JIS対応版のインストール方法
$ git clone https://github.com/ted-n/unzip.git
$ cd unzip/unzip60
$ make -f unix/Makefile LOCAL_UNZIP="-D_FILE_OFFSET_BITS=64 -DNO_LCHMOD -D_MBCS -DNO_WORKING_ISPRINT" generic_gcc
$ sudo make -f unix/Makefile install

これで、/usr/local/bin 下にパッチの当たった unzip がインストールされる。
一行目を修正("git clone git@github.com:ted-n/unzip.git"としていたが、これは予めSSH Keyの設定が必要なため)

【UTF-8 エンコード時】

$ /usr/local/bin/unzip -l ./AmazonMusicDownload.zip
Archive:  ./AmazonMusicDownload.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
  8381815  10-11-2015 01:53   氷堂美智留(矢作紗友里)/Cherish you/01 - Cherish you.mp3
  9099388  10-11-2015 01:53   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/03 - 饒舌スキャンダラス.mp3
---------                     -------
 25928618                     3 files

【Shift-JIS エンコード時】

$ /usr/local/bin/unzip -l ./sjis-sample.zip
Archive:  ./sjis-sample.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  10-11-2015 10:59   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/
  9099388  10-11-2015 01:53   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/03 - 饒舌スキャンダラス.mp3
        0  10-11-2015 10:59   氷堂美智留(矢作紗友里)/Cherish you/
  8381815  10-11-2015 01:53   氷堂美智留(矢作紗友里)/Cherish you/01 - Cherish you.mp3
---------                     -------
 25928618                     5 files
Python で Shift-JIS エンコードしたファイル名で圧縮する場合の注意

自分はこれまで、Linux(CentOS) 上の Python で日本語ファイル名を含んだ ZIP ファイルを作成する場合でも、Windows で扱いやすくするために Shift-JIS(CP932) でエンコードしたファイル名で圧縮していたのだが、こうして作成したファイルを上記のパッチ済みの unzip で表示すると、なぜか文字化けしてしまった。

【オリジナルの unzip 6.0 使用時】

$ /usr/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:57   ???{????f?B???N?g??/???{???t?@?C????.txt
---------                     -------
      400                     1 file

【パッチ済みの unzip 使用時】

$ /usr/local/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:57   傔
                                ・fB
                                    Ng
                                      /傔
                                         黎@C
                                             シ.txt
---------                     -------
      400                     1 file

調べてみると、どうも ZIP ファイルヘッダの version(ZipInfo.create_system) が 3 (Unix) になっているとこの現象が発生するようなので、これを考慮して Python スクリプトを作成する必要がある模様。
zipfile.py の class ZipInfo の定義を見てみると、sys.platform が 'win32' のときは self.create_system に 0 が、それ以外は 3 がデフォルトで設定されている。

【例】

import czipfile as zipfile
import datetime

zip = zipfile.ZipFile( 'test.zip', 'w' )
timestamp = datetime.datetime.now()
dir_filename = u'日本語のディレクトリ/日本語ファイル名.txt'
content = 'test' * 100

zipinfo = zipfile.ZipInfo(
  filename = dir_filename.encode( 'cp932', 'replace' ),
  date_time = ( timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second )
)
zipinfo.compress_type = zipfile.ZIP_DEFLATED
zipinfo.create_system = 0 # 0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems), 3 - UNIX (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)

zip.writestr( zipinfo, content )
zip.close()
$ /usr/local/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:59   日本語のディレクトリ/日本語ファイル名.txt
---------                     -------
      400                     1 file

追記(2015/10/26)