今回からは、FSRefで参照したファイルやフォルダ(ディレクトリ)への基本的なアクセス(作成、書き込み、読み込み、削除など)について調べて行きます。まずはファイルを作成することから始めてみましょう。
Carbon Frameworkでファイルを作成する場合には、FSCreateFileUnicode() APIを利用します。このAPIを含め、ファイルアクセスに関係するAPIは、すべてヘッダーファイルのFiles.hに定義されています。

最初のparentRefでファイルを作成する親ディレクトリ(フォルダ)の場所を指示し、次のnameLengthとnameでファイル名(ユニコード)を指示します。whichInfoは、作成したファイルに対して何かしらの情報を設定したい場合のみ指定します。指示は、unsigned long値の各ビットを立てることで行います。その場合には、情報格納場所としてのcatalogInfoにFSCatalogInfo構造体の先頭アドレスをセットしておきます。もし何も情報を指定しななければ、whichInfoにはkFSCatInfoNoneをセットし、catalogInfoの方はNULLでかまいません。最後のnewRefとnewSpecには、作成されたファイルのFSRefとFSSpec構造体が代入されますが、こちらも必要がなければ、それぞれNULLを代入しておきます。
FSCreateFileUnicode()は、ファイルを作成するだけなのにやけに引数が多いですね。そこで、親ディレクトリ(FSRef)とファイル名(CFStringRef)を与えるだけの簡単なファイル作成ルーチンを別途用意してみます。ルーチン名はcreateFile()です。正しくファイルが作成できた場合には、そのファイルのFSRefを返してきます。

CFStringRefで定義されたファイル名は、CFStringGetCharacters()を使いユニコード文字列へと変換されています。先んじてFSMakeFSRefUnicode()を呼び出しているのは、同じ名称のファイルが存在しているかどうかを確認するためです。もし同じ名称のファイル(もしくはディレクトリ)が存在していると、FSMakeFSRefUnicode()がnoErr(ゼロ)を返しますので、そのファイルをFSDeleteObject()で削除してしまいます。この削除処理に関しては、用途によっては実行せずエラーを返すだけの方が良いケースがあるとおもいますので、利用する場合には注意してください。ちなみに、削除せずにFSCreateFileUnicode()を実行するとエラーが返ります。
同様な引数を与えることで、ファイルではなくディレクトリ(フォルダ)を作成する場合には、以下のFSCreateDirectoryUnicode()を利用します。FSCreateFileUnicode()より引数がひとつ多いのですが、最後の引数には作成されたディレクトリのディレクトリID番号(unsigned long値)が返ります(不必要ならNULL指定)。こちらの場合には、すでに同名ディレクトリが存在していれば削除する必要はないので、エラーを返すだけの処理となっています。

後から作成したファイルの各種情報を得たい場合にはどうしたら良いのでしょうか?例えば、先ほど用いたFSMakeFSRefUnicode()を単独で使うことで、指定ファイルのFSRefを得るルーチンなどは簡単に作成することができます。

もっと詳しい情報を得たい場合には、次のFSGetCatalogInfo() APIを利用します。

例えば、引数で対象ファイルのFSRefを渡して、そのファイルの親ディレクトリ(ファイルが入っているフォルダ)のFSRefを得たい場合には、以下のようなルーチンを用意しておくと便利です。

FSCatalogInfoBitmapを設定することで、FSCatalogInfo構造体に様々なファイル情報が書き込まれてきます。それらは、ファイル作成日時や編集日時、ファイル容量、アクセス権(パーミッション)情報からFinder情報まで多種多様です。どんな情報を得られるのかは(作成時に設定する場合も同様)、Files.hに詳しく記載されていますので参照してみてください。上記ルーチンと同様に、目的に応じた情報を得るためだけのルーチンを用意しておくと便利かもしれません。
今まで紹介してきたルーチンは、ファイル名をCFStringRef定義で渡していますが、代わりにHFSUniStr255構造体として渡したい場合もあります。Files.hには、CFStringRefをHFSUniStr255構造体に変換(もしくはその逆を)するためのAPIが用意されていますので、それを使えばファイル名を好みの文字列フォーマットで指示できます。HFSUniStr255構造体からCFStringRefを得るにはFSCreateStringFromHFSUniStr()を、また逆の処理にはFSGetHFSUniStrFromString()を使います。
CFStringRef FSCreateStringFromHFSUniStr( CFAllocatorRef alloc,const HFSUniStr255 *uniStr);
OSStatus FSGetHFSUniStrFromString( CFStringRef theString,HFSUniStr255 *uniStr);
一番最初のcreateFolderFile()をFSGetHFSUniStrFromString()を使うように書き直すと、以下のようになります。

次回は、ファイルのオープン(Open)とクローズ(Close)ファイルへのデータ書き込み(Write)とファイルからの読み込み(Read)、ファイルの削除(Delete)やファイル名の変更(Rename)など、一般的なファイル処理を調べてみる予定です。