8.1ストアアプリ向けのファイルアクセス機能の改善点から、例外が出ないファイルやフォルダーの取得と、パスに依存しないファイルやフォルダーの等価比較を紹介。8アプリ)ではファイルが正常に開けることを試してみるしかなかった。8.1アプリ)から利用できるWindowsランタイム(以降、WinRT)*1には施されている。本稿では、その改善点の中から、例外が出ないファイルやフォルダーの取得と、パスに依存しないファイルやフォルダーの等価比較を紹介する。8.1版)」からダウンロードできる。まことに回りくどい表現で申し訳ない。MSDNのWinRTのドキュメントには、今のところバージョン番号などが記されていないため、利用できる側のバージョンで区別するしかないのだ。その利用する側であるWindowsストアアプリにもバージョン番号などによる区別がないため、その実行環境であるOSのバージョンにさかのぼって区別するしかないのである。2013)が必要である。Windows(日本語版)を使用してプログラミングしている。8.1]」の記事をご参照いただきたい。Windows(日本語版の製品版)*3でも動作を確認している。8.1Preview版の使用期限は来月(2014年1月)の半ばまでとなっている。Windows」から無償で入手できる。8.1で改善されたファイルアクセス機能MSDNによれば、次のような改善が施されている。ファイルの関連付けによって起動されたときに引数として受け取るFileActivatedEventArgsオブジェクト(Windows.ApplicationModel.Activation名前空間)にNeighboringFilesQueryプロパティが新設された。8アプリでは、ファイルやフォルダーを取得してみて例外が出たらファイルが存在しなかったと判定するしかなかった。指定したフォルダーの中に指定したファイルが存在するかどうかを判定するメソッドは、次のコードのように記述していた。8で、指定したフォルダーの中に指定したファイルが存在するかどうかを判定するメソッド(上:C#、下:VB)例外をキャッチするのはパフォーマンス的に不利である。何をやっているコードなのか分かりにくかった。8.1では、StorageFolderクラス(Windows.Storage名前空間)にTryGetItemAsyncメソッドが新設された。このメソッドは、ファイルが存在しないときには例外を出すのではなく、null/Nothingを返す。先ほどと同じメソッドが、簡潔に分かりやすく記述できるようになった(次のコード)。8.1で、指定したフォルダーの中に指定したファイルが存在するかどうかを判定するメソッド(上:C#、下:VB)TryGetItemAsyncメソッドは、名前が一致したファイルまたはフォルダーを返してくる。そこで、例えばファイルだけが欲しいときは、上のコードのようにStorageFileクラス(Windows.Storage名前空間)へのキャストを試みる。これで、TryGetItemAsyncメソッドがフォルダーを返してきたときでも、file変数にはnull/Nothingが入るようになる。TryGetItemAsyncメソッドは、ファイルやフォルダーの名前として不適切な文字列(例えば、「.」「*」「\」など)を渡した場合には、これまでどおりに例外を発生する。エンドユーザーからの入力をそのまま使う場合には、例外をキャッチするコードを書くべきである。8でストレージアイテムの等価比較をする方法の問題点ストレージアイテム(=ファイルやフォルダー)のオブジェクトが2つあったとき、それらが同じファイルやフォルダーを指しているかを調べたいときがある。ファイルオープンピッカーを出してエンドユーザーに選択してもらったファイルが、すでにアプリで開いているファイルだった場合はその画面に切り替えるなどだ。8アプリでは、次のコードのようにしてストレージアイテムのパス文字列を比較していた。8で、2つのストレージアイテムの等価比較をするメソッド(上:C#、下:VB)この方法は少々煩雑なだけでなく、致命的な問題を抱えていた。特定のフォルダーが正しく比較できないのである。上のコメントにも書いたが、[ライブラリ]の下にあるフォルダーがそうだ。エンドユーザーがフォルダーピッカーのドロップダウンで[ライブラリ]を選び(次の画像)、その下のフォルダーを選択した場合には、得られるStorageFolderオブジェクトのパスがString.Empty(=空文字)になってしまうのだ。これでは、例えば[ライブラリ]の下にある[ピクチャ]フォルダーと[ビデオ]フォルダーの区別が付かない。8.1)この画像のように、トップレベルの選択肢として[ライブラリ]がある(マウスカーソルのあるところ)*4。これを選んで、次にその下のフォルダー(例えば[ピクチャ]フォルダーなど)を選択した場合、アプリに返されるStorageFolderオブジェクトのパスが空文字になってしまう。この画像で[ホームグループ]を選んで進めていっても同じだ。この画像で[PC]を選び、その中の[ピクチャ]フォルダーなどを選んだ場合には、パス文字列が得られる。[ライブラリ]が表示されない場合は、デスクトップのエクスプローラーで表示設定を変更してほしい。8.1のエクスプローラにライブラリ項目を表示させる」を参照。8.1では、IStorageItem2インターフェース(Windows.Storage名前空間)が新設された。そのIsEqualメソッドを使えば、正しくストレージアイテムの等価比較ができる。フォルダーを表すStorageFolderクラスも、ファイルを表すStorageFileクラスも、このIStorageItem2インターフェースを実装している。2つのストレージアイテム・オブジェクトの等価比較をするメソッドは、次のコードのように書ける。8.1で、2つのストレージアイテムの等価比較を常に正しく行うメソッド(上:C#、下:VB)ちなみに、ストレージアイテムのパスが空文字のとき、IsEqualメソッドはその内部でShell32.dllのIShellItem::Compareメソッドを呼び出している。8アプリで同様なことをするには、C++/CXでDLLを作るしかなかったのだ。8.1では、ファイルアクセス関連のAPIも改善されており、ファイルやフォルダーの存在確認や等価比較が簡単になった。8.1ではロジックで使うAPIにもさまざまな改良が加えられている。新しくなったAPIについては、次のドキュメントも参照してほしい。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。