タイトルBrowsing Mac OS X》Carbonアプリケーションでロングファイルネームに対応するには(1)カテゴリーMac OS X, Browsing Mac OS X
作成日2001/3/31 17:9:6作成者新居雅行
HFS+ボリュームのいちばんの売りは、なんと言っても255バイトまでのファイル名を扱えることだった…が、初めて搭載されたMac OS 8.1ではそのメリットはまったく生かされていなかった。それは、「ファイル名は31バイトまで」というMac OSの従来の縛りがあり、仮にボリュームでそうした制約がなくなったとしても、アプリケーションなどが対応しないと意味がないからである。また、Mac OSの方も、なぜか64バイトまでの構造体を用意していたのだが(理由は後述)、いずれにしても、255バイトまでのファイル名に対応する道のりは遠かったと言えるだろう。
さらに、Mac OS 9では、255バイトのファイル名を扱えるAPIセットが用意され、アプリケーションとしては255文字までに対応するということが可能になった。Javaの実行環境であるMRJでは、ここで255バイトのファイル名に対応する。しかしながら、肝心なFinderがやっぱり31バイトまでだったため、255文字を使えるアプリケーションは皆無だったのではないだろうか。対応する気になれないというやつだ。
だが、Mac OS Xが発売された。Mac OS Xでは、Finderはもちろん、システムのすべての領域に渡って、ファイル名は255バイトまでの文字列が許される。しかしながら、古いFile Managerの機能を使っている場合には、そこで制限が出てくる。Carbonアプリケーションを移植している方などは、ファイル名の問題も要注意だと言えるようになってきた。
たとえば、StuffIt Deluxで、31バイトを超えるファイルを圧縮してみよう。すると、アーカイブファイルでは31バイトに切り詰めてしまう。また、31バイトを超える長さのファイルが、tar形式のファイルにあったとしても、やっぱり31バイトに切り詰めてしまう。システム標準のユーティリティでさえこうした状態なのであるが、やはり開発者としてはいつかはクリアしないといけない点だけに、ファイル名の問題解決の目処を立てたいところだろう。現状のバージョンのJeditのように、32バイトを超えるファイル名は扱えないとしっかり警告を出すという場合もある。
そこで、Carbon系プログラマに対しての255バイト対応についての説明を行いたい。なお、CocoaやJavaは最初から255バイトのファイル名の文字列に対応しているので、基本的にはこうした問題は発生しない。

□31バイトファイル名とFSSpec
File Managerの変遷はいろいろあるが、System 7あたりで、FSSpec構造体を使って、処理するファイルを特定する手法が定着したと言える。このFSSpecは、ボリューム、所属フォルダ、ファイル名(あるいはフォルダ名)という3つのパラメータ記録する構造体だ。ボリュームや所属フォルダはID番号なのであるが、ファイル名は64バイトの文字列である。なぜ31バイトなのに64バイトになるかと言うと、ここに部分パス名やフルパス名を指定して、構造体を構築するという機能を組み込んだからである。そのときに、なんで256バイトにしなかったのかと言ってももう遅い。FSSpecは255バイトのファイル名を特定するためには利用できなくなってしまったのである。このFSSpecを基調にしたFile ManagerのAPIを一般的に使うようになってしまった。
では、HFS+のボリュームに、31バイトを超える長さのファイルを作成したとしよう。Mac OS 9でもJavaを使えば作成できるし、Mac OS XだとFinderでファイル名を書き換えればよい。その場合、FSSpecの世界から見ると、ファイル名を切り詰めて、31バイトの長さのファイル名を持つファイルだとして参照できるようになっている。また、そのときに、末尾の拡張子は保存したまま、拡張子直前の文字を取り除く。単に取り除くだけでなく拡張子の直前に#2345のようなシリアル番号を振ることで、文字列を取り除いたことによるファイル名の重複をさけるようにもなっている。だから、HFS+で31バイトを超えるファイル名のものは、Mac OS 9のFinderでは切り詰めてシリアル番号が振られた31バイトのファイル名で見えるわけだ。このファイル名は、FSSpecベースのAPIでは有効なのである。
このFSSpecを使ったファイルアクセスの機能は、Mac OS XのCarbonでも利用できる。その意味では、従来のアプリケーションのファイル処理についてはほぼ手を加えなくても、Mac OS Xでは実行できるようになっている。しかしながら、それはそれで問題の元になる可能性がある。たとえば、StuffiItのように、ファイル名をアプリケーションの中で扱いしかもユーザに見せるような場合には、Mac OS Xでは切り詰めたファイル名を出してしまう。一般にはそれでは許されないことだ。また、文書ファイルを開くと文書ファイル名を、ウインドウのタイトルに表示する。そこでも、Finderで見えるファイル名と微妙に違うきりつめた名前ではどうだろうか。もっとも、ほんとうに255バイトのファイル名をつけてしまった場合にはウインドウのタイトルには入らないにしても、いずれにしても、ファイル名の255文字対応は、Mac OS Xでは必須となっている。
なお、従来はファイル名はシステムのエンコードだったために漢字などはShift-JISの2バイトで保存されていた。HFS+では、ファイル名はUNICODEとなり、しかもUTF-8でのエンコーディングとなっている。従って、アルファベットなら255文字と言えなくもないが、全部日本語のファイル名なら、85文字にしかならない。255だとほぼ無限大とも言えるけど、85文字と言うのは青天井とは言いがたいような気がする。

□255バイトのファイル名を扱えるAPIセット
Mac OSの時代にHFS Plus APIなどとして公開は始まっていたが、255バイトまでのファイル名を扱えるAPIはすでに使える状態になっている。そのキーになる、ファイルやフォルダを特定するための構造体は、FSRefというものになった。この構造体の中身は隠されており、単に80バイトのデータブロックであるということしか分からない。ただし、FSRefを使う限りは、HFS+であろうがUFSであろうが統一的に扱えるということになっている。つまり、ファイルシステムの違いを隠ぺいした構造体である。きっと将来に渡ってもOKというのを狙っているのだろう。たとえば、ファイル名が1024バイトまでに拡張されても、FSRefならシステム側が対応することで同じAPIで対応できるのではないかと思う。
それじゃあ、FSSpecをFSRefに置き換えればいいかと言うと、そんなことは絶対にない。FSSpecではファイル名などを構造体のメンバ変数にアクセスすることで得ていたが、FSRefではそれはできない。ファイル名を取り出すにしても、APIコールを呼び出すようになっている。従って、ファイル処理関連の部分は、ほとんど書き直すことになると言っても良いだろう。
APIについてはすでに公開されているのでそれを参考に作業にかかることも可能だ。また、File Managerを知っている方は、パラメータブロック系の複雑怪奇なAPIをまた1から覚えなおすのかとうんざしするかもしれないが、FSRefを使ったAPIはかなり整理されているので、その点は安心してよい。ただし、必ずパラメータブロックは使う必要があると言える。以前はパラメータブロックはローレベルのファイル処理という感じだったが、FSRef対応のAPIでは、たとえばファイルタイプやクリエイタを得るような作業でも、パラメータブロックは使う。ただ、たくさんのパラメータブロックはないので、明解さについては明らかにFSRefの方が上である。
(続く)
関連リンク