ファイル名の長さと文字コードの問題
あるシステムで、ファイルをZIPで圧縮する仕組みを作っていました。ZIPで圧縮する処理はLinuxで行うのですが、解凍するのはWindowsがメインということで、結構面倒なのです。。
まず、文字コードの問題があります。LinuxやMacOSでは、ファイル名は一般的にUTF-8です。WindowsはNTFSではUNICODEらしいのですが、アプリではShift_JIS(CP932)になるらしいです(あまり興味ないので・・・)。そのため、ZIPで固める際に、UTF-8のまま固めると文字化けしてしまいます。仕方ないので、LinuxやMacOSで無理矢理CP932のファイル名でファイルを作ってZIPで固めるとうまくいきます。が、MacOSでCP932のファイル名を作るとOSごと重くなることが多い気がするのでLinuxの方がマシです。。
さて、文字コードの問題をクリアーしたと思うと、今度はファイル名の長さの問題が立ちふさがります。Windowsではパスも含めて256文字までらしいので、長いファイル名はエラーになってしまいます。仕方ないので、長いファイル名は切り詰めるしかないのですが、ASCII文字の切り詰めは簡単ですが、マルチバイト文字の切り詰めは面倒です。適当なところで切ってしまうと文字化けしてしまいます。仕方ないので、C言語などではワイド文字に変換して切り詰めて、またマルチバイトに戻す感じになります。
昔はWindowsはCP932、UNIX系はEUCが多くて、どちらも日本語は2バイトという想定が使える場合が多かったのですが、インターネットが普及して世界各国の文字が共存するようになってきて、マルチバイトは2バイトどころではなくなってしまい、自力で何とかするのは大変になってしまいました。素直にマルチバイト処理ようのライブラリを使うのが良いでしょう・・・。
さらに・・・Windowsではファイル名に使えない文字が存在します。'/'':'';'',''?''"''<''>''|''\'このあたりの文字は使わない方が無難です。Linuxでも'/'と'¥0'は駄目ですね。ということで、これらの文字は置き換えが必要です。置き換えもワイド文字状態で行う方が確実です。
これでようやくWindowsで解凍できる見込みのファイル名にすることができます。「見込み」というのは、パスの長さが256文字までなので、展開するディレクトリによってはオーバーしてしまったりする可能性もあるためです。
ちなみに、LinuxなどのUNIX系OSでは、ファイル名の最大長は255バイト。パスの最大長は1023バイト(システムコールに渡す際の制限)と、Windowsよりはかなり扱いやすくなります。
まあ、そんなに長いファイル名など関係ないと思うかもしれませんが、プログラムを作っていると、限界テストという感じで、あえておかしな動きになりそうなデータを与えてテストをするものでして。。
正常系の処理を作るより、異常系の処理を作る方が大変なこともよくあるくらいなのです。特にユーザが直接操作する部分は、何をされても大丈夫なように、と、大変です。ユーザインターフェースなどはまさにエラーチェックなどだけで嫌になるくらいです。
ワイド文字の扱い方を忘れていたので、著書を引っ張り出してきました。すでに絶版ですが・・・。