So-net無料ブログ作成

Windows非互換ファイル削除アプリ - その3 [プログラミング]

前々回にいきさつ、前回でFATボリューム上のリソースフォークの入ったファイルを消去するひとつのやりかたを紹介した。今日はボリュームのフォーマットを確認したりアンマウントする方法について。

4  NSWorkspace

findコマンドでUSBボリュームの中にある特定のファイルを削除することが簡単にできた。次はUSBボリュームを取り外す(unmountする)にはどうするか、ということ。

CocoaからはUSBメモリなんかがささってるかどうかはNSWorkspaceに問い合わせればいい。
- (NSArray *)mountedRemovableMedia;
は光ディスクやUSBメモリなどRemovebleなボリュームのフルパスを返す。
取り外すには
- (BOOL)unmountAndEjectDeviceAtURL:(NSURL *)url error:(NSError **)error;
を呼ぶ。mountedRemovableMediaではパスなのにこっちはURLになっているのは、10.6で新しく追加されたメソッドのため。

これまでは
- (BOOL)unmountAndEjectDeviceAtPath:(NSString *)path
というのを使うことになっていた。こっちはもしエラーが起こって取り外せなかった場合、その原因はわからないのでユーザへのフィードバックが不親切になってしまう。

ファイルシステムのフォーマットがなんなのか、というのはやはりNSWorkspaceのちょっと変わったメソッド
- (BOOL)getFileSystemInfoForPath:(NSString *)fullPath
                     isRemovable:(BOOL *)removableFlag
                      isWritable:(BOOL *)writableFlag
                   isUnmountable:(BOOL *)unmountableFlag
                     description:(NSString **)description
                            type:(NSString **)fileSystemType
で問い合わせることができる。

ユーザにドラッグアンドドロップで取り出したいUSBメモリを指定してもらうんだけど、ひょっとしたらただのテキストファイルをドロップするかもしれない。取り外せない場合、なぜできないか、をフィードバックしないといけない。普通のファイルやディレクトリを渡されたら、「それはできません」といわなければならない。従ってまず、指定されたものがなにかを調べる必要がある。

これにはいろいろな方法があるけど、いちばん簡単なのは渡されてきたパスのUTI(Uniform Type Indentifier)を調べるという手。それもNSWorkspaceでできる。
- (NSString *)typeOfFile:(NSString *)absoluteFilePath error:(NSError **)outError
これはパスを渡せばUTIを返してくる。パスにファイルが存在しないか、拡張子も付いてなくて中身も空っぽ、なんていう以外はだいたい失敗しない。

具体的なUTIは山ほど定義されているけど、今回必要なのは
UTI 定数(CFString) 説明
public.directory kUTTypeDirectory ディレクトリ
public.folder kUTTypeFolder フォルダ
public.volume kUTTypeVolume ボリューム
com.apple.package kUTTypePackage パッケージ
com.apple.bundle kUTTypeBundle バンドル
com.apple.application-bundle kUTTypeApplicationBundle アプリケーション
ぐらいが区別できればいい。説明がほとんど説明になっていないけど。どれもディレクトリの一種で、これ以外は普通のファイルか、シンボリックリンクやエイリアスになる。

前回のfindコマンドとこのモリュームの扱いを組み合わせれば、今回のアプリができあがる、という結論。簡単々々。どっとはらい。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0