タイトル鶴薗賢吾のCocoaはやっぱり!出張版》#4-Mac OS X 10.1の新機能(4)カテゴリーCocoa, 鶴薗賢吾のCocoaはやっぱり!出張版
作成日2001/10/4 16:3:34作成者新居雅行
■ Foundationの新機能

◎ファイルタイプとクリエータ

Mac OS X 10.0.4までの二大フレームワークでは、ファイル属性のファイルタイプとクリエータに関しては、サポートがあまりなされていませんでした。そのために、Carbon APIを呼ぶ必要がありました。10.1になってようやくNSFileManagerクラスでサポートが行われるようになりました。ファイルの属性を取得するメソッドを使うことで、ファイルタイプとクリエータの情報も同時に取得できます。

★NSFileManager : ファイル属性を取得する
[書式] - (NSDictionary *) fileAttributesAtPath : (NSString *) path
   traverseLink : (BOOL ) yorn
[入力] path : 属性を取得したいファイルのパス
   yorn : リンクを辿るなら - YES、辿らないなら - NO
[出力] 返り値 : ファイルの属性が格納された辞書

このように、返り値が辞書になっていますので、ファイルの属性が沢山詰まった辞書のインスタンスが返ってくることが分かります。以下のようにすると、指定のファイルパスのファイル属性が得られます。

// filePathに存在するファイル属性の辞書の表示
NSLog( @"%@", [ [ NSFileManager defaultManager ]
fileAttributesAtPath : @" filePath "
traverseLink : YES ] );

実行結果は以下のようになります。

ファイル属性の辞書のサンプル
2001-XX-XX 16:31:55.374 FileTypeCreator[428] {
NSFileExtensionHidden = 0;
NSFileGroupOwnerAccountName = staff;
NSFileHFSCreatorCode = 943868237;
NSFileHFSTypeCode = 1246774599;
NSFileModificationDate = 2000-12-08 19:40:46 +0900;
NSFileOwnerAccountName = crane;
NSFilePosixPermissions = 511;
NSFileReferenceCount = 1;
NSFileSize = 4003;
NSFileSystemFileNumber = 282823;
NSFileSystemNumber = 234881033;
NSFileType = NSFileTypeRegular;
}

様々な属性があることが分かりますが、この中でファイルタイプとクリエータに当たるのが、NSFileHFSTypeCodeとNSFileHFSCreatorCodeです。この2つは、ファイルタイプとクリエータを辞書から取り出したり、辞書へ書き込んだりするときに使用するキーになります。

ファイルタイプとクリエータは、4文字の文字列として見ることが多いですが、ここでは、unsigned longの形式で数値として表記されています。文字に変換するとファイルタイプが「 JPEG 」で、クリエータが「 8BIM ( Adobe Photoshop ) 」になります。この辞書からファイルタイプとクリエータを取り出す専用のメソッドも用意されています。

★NSDictionary : 辞書からファイルタイプを取得する
[書式] - (OSType) fileHFSTypeCode
[出力] 返り値 : ファイルタイプ

★NSDictionary : 辞書からクリエータを取得する
[書式] - (OSType) fileHFSCreatorCode
[出力] 返り値 : ファイルタイプ

OSTypeという型の実体はunsigned longで、そのままCocoaで扱う場合は不便なため、文字列との相互変換を行う関数が用意されています。

★OSTypeからNSStringに変換
[書式] NSString *NSFileTypeForHFSTypeCode( OSType hfsFileTypeCode )
[入力] hfsFileTypeCode : NSStringに変換したいOSType
[出力] 返り値 : 変換されたNSString。前後にシングルクォートがつく ( 例’TEXT’ )。

★NSStringからOSTypeに変換
[書式] OSType NSHFSTypeCodeFromFileType( NSString *fileTypeString )
[入力] fileTypeString : OSTypeに変換したいNSString
  前後にシングルクォートが必要 ( 例’TEXT’ )
[出力] 返り値 : 変換されたOSType

以上で道具がそろいましたので、指定のファイルパスからファイルタイプとクリエータをNSStringで取得するサンプルコードを以下に書きます。

// ファイルパスからファイルタイプとクリエータをNSStringで取得
NSFileManager *fm = [ NSFileManager defaultManager ];
NSDictionary *dic = [ fm fileAttributesAtPath : filePath
traverseLink : YES ];

NSLog( @"%@", NSFileTypeForHFSTypeCode( [ dic fileHFSTypeCode ] ) );
NSLog( @"%@", NSFileTypeForHFSTypeCode( [ dic fileHFSCreatorCode ] ) );

ファイル属性を書き込む以下のメソッドも、もちろんファイルタイプとクリエータに対応しています。

★NSFileManager : ファイル属性を変更する
[書式] - (BOOL) changeFileAttributes : (NSDictionary *) attributes
    atPath : (NSString *) path
[入力] attributes : 変更したいファイルの属性
    path : 属性を変更したいファイルのパス
[出力] 返り値 : 成功 - YES、失敗- NO

ファイルタイプとクリエータを変更するサンプルは、以下のようになります。

// ファイル属性を変更するサンプル

// ファイル属性を取得
NSString *filePath = @"ファイルパス";
NSFileManager *fm = [ NSFileManager defaultManager ];
NSDictionary *dic = [ fm fileAttributesAtPath : filePath
traverseLink : YES ];
// ファイル属性をコピー
NSMutableDictionary *dicNew = [ NSMutableDictionary
dictionaryWithDictionary : dic ];

// OSTypeを準備
OSType fileType = NSHFSTypeCodeFromFileType( @"’ImgV’" );
OSType creator = NSHFSTypeCodeFromFileType( @"’JPEG’" );

// NSNumberを準備
NSNumber *numFileType = [ NSNumber numberWithUnsignedLong : fileType ];
NSNumber *numCreator = [ NSNumber numberWithUnsignedLong : creator ];

// ファイル属性辞書を変更
[ dicNew setObject : numFileType
forKey : NSFileHFSCreatorCode ];
[ dicNew setObject : numCreator
forKey : NSFileHFSTypeCode ];

// ファイル属性を変更
[ fm changeFileAttributes : dicNew
atPath : filePath ];

◎リソースフォークの扱いの改善

MacOS X 10.0.4までは、NSFileManagerに存在しているファイルコピーなどのメソッドは、リソースフォークを無視していました。コピーするとリソースフォークが落ちてしまい、事実上使いものにならなかったのですが、Mac OS X 10.1でようやくリソースフォークにも対応してくれました。以下に、ファイル移動のサンプルだけ書いておきます。ファイル操作については、NSFileMangerに色々と用意されていますので、リファレンスを参照ください。

//ファイル移動のサンプル
NSFileManager *fm = [ NSFileManager defaultManager ];
BOOL bResult;

NSString *srcPath = @"移動元";
NSString *dstPath = @"移動先";
bResult = [ fm movePath : srcPath
toPath : dstPath
handler : nil ]; // 移動

[鶴薗賢吾]
関連リンクCocoaはやっぱり!