Gauche で日本語ファイル名

[追記] この問題は Gauche の方で対処されました。 コミット 1456e4d 以降では Windows 上でユニコードのファイル名を持つファイルの読み書きが出来ます。 [/追記]

Scheme 処理系 Gauche は内部的に使う文字コードとして UTF-8 を採用している。 コンパイル時に内部文字コードを選択することも出来て euc-jp や sjis も選択肢として用意されているが、もうほとんどの人は UTF-8 で使っているだろう。 将来的には UTF-8 のみにする可能性も示唆しており、時世を考えると自然な処置だと思う。

言語処理系における文字コードの戦略を大まかに分けると以下のみっつに分けられる。

  1. 内部的には一貫した文字コードを使う。 必要なら入出力の段階で変換をかける。
  2. 各文字列は自分がどの文字コードを使われているか知っている。
  3. 文字コードを無視する。 言語処理系レベルでは単なるバイト列であり、それをどう解釈するかはプログラマの裁量にまかせる。

Gauche の場合はひとつ目の戦略だ。

さて、入出力に使う文字コードは置くとして、ファイル名についてはどうだろう。 Gauche でこんなプログラムを走らせた結果はどうなるだろうか。

#!/usr/bin/env gosh
;; -*- coding: utf-8 -*-

(call-with-output-file "日本語ファイル名.txt"
  (pa$ write "test"))

ロケールUTF-8 に設定された近年の UNIX 風 OS の上ではこれで何の問題もなく日本語ファイル名のファイルが生成されると思う。 ところがロケールUTF-8 以外の場合、または Windows 版ではそう単純な話ではない。

saito@longarch ~/test
$ ./test.scm

saito@longarch ~/test
$ ls --show-control-chars -l
total 2
-rwxr-xr-x 1 saito Administrators 127 Apr  7 23:45 test.scm
-rw-r--r-- 1 saito Administrators   6 Apr  7  2014 譌・譛ャ隱槭ヵ繧。繧、繝ォ蜷・txt

化けてしまった!

Windows で日本語ファイル名のファイルを作るには CP932 (Shift JIS) に変換すればいい。

#!/usr/bin/env gosh
;; -*- coding: utf-8 -*-
(use gauche.charconv)

(define fsencode (cut ces-convert <> (gauche-character-encoding) 'cp932))

(call-with-output-file (fsencode "日本語ファイル名.txt")
  (pa$ write "test"))

実行するとちゃんと日本語ファイル名のファイルが作られる。

saito@longarch ~/test2
$ ./test2.scm

saito@longarch ~/test2
$ ls --show-control-chars -l
total 2
-rwxr-xr-x 1 saito Administrators 238 Apr  8 00:22 test2.scm
-rw-r--r-- 1 saito Administrators   6 Apr  8 00:22 日本語ファイル名.txt

が、本当にこれで大丈夫かというと微妙なところがある。

まずひとつ目の問題は全ての Windows 環境でコードページが CP932 (Shift JIS) に設定されているとは限らないという点だ。 作ったプログラムを github にでも置けば外人の目にとまることだってあるだろう。 実行してみてエラーでは困る。

そしてふたつ目の問題は CP932 に含まれない文字をファイル名に付けることが不可能であるという点だ。 Windows (と NTFS) はファイル名に Unicode を使えるにもかかわらず CP932 の文字コードに制限されるのは困る。

私が公開しているニコニコ動画ダウンローダではスクリプトの頭にある変数を指定することで簡単に文字コードを変更できるようにして対処しているが、環境によってはほとんど変換できずゲタだらけになってしまうだろう。 (例えば日本語の文字コードトルコ語文字コードに変換することを考えてみるといい。 ほとんどの文字はトルコ語の文字セットに含まれないので変換不能である。)

https://github.com/SaitoAtsushi/niconico-downloader

自分が使う分には当然ながら日本語の範囲だけを考えれば問題ないのだが、汎用的にしようと思うとどんなに細かく場合分けしてもカバーできない部分があるので、 Gauche の方で対処してくれるとありがたいなぁと思う。

Document ID: 957e9ebf930cd02671caa5e41706bf87