VC2005 MFC です。
同じ場所を指している、異なるファイルパス文字列に対して
必ず同じ文字列が返ってくるようにする方法はありますでしょうか。
ファイルパス名の文字列(場所)をキーとしたCMapを作りたいのですが、
大文字/小文字や相対/絶対などいろいろな表記方法があるので、
同じ場所を指している2つのキーが作られてしまわないようにしたいです。
現在は、渡されたファイルパス名が絶対パスだろうが相対パスだろうが
GetCurrentDirectory()とPathAppend()を使って必ず絶対パスに変換し、
PathCanonicalize()を使って無駄な部分を省き、
最後に小文字に変換した文字列をキーとしてみましたが、
これでも同じ場所を指しているのに異なるキーになってしまう可能性は
ありますでしょうか?
もしくは、もっと簡単に作成できる方法はありますでしょうか?
「異なる絶対パスが物理的に同じ場所を指し示す可能性はあるのか」
という質問になるかと思いますが、それは「ありえる」ではないでしょうか。
1.あるフォルダをドライブに読み替えている場合。
2.ネットワークドライブを割り当てている場合。
などが想像できますが、どうでしょう。
この辺読むと頭が痛くなると思います。
http://www.ipa.go.jp/security/awareness/vendor/programming/b08_01.html
> GetCurrentDirectory()とPathAppend()を使って必ず絶対パスに変換し、
だったら GetFullPathName を使うべきです。
> PathCanonicalize()を使って無駄な部分を省き、
が前述の IPA のサイトに書いてあるようなのにどこまで対応しているかですね。
あとは、ハードリンクとかジャンクションとかをどう扱うかとか。
あとはあとは、大文字と小文字が非可逆変換になっちゃう文字もあったような。ファイル
パスには Unicode を使えますので、日本語と英語アルファベットだけ考えていていいの
かどうかわかりません。
私の場合なら、客先との要求にもよりますが、ファイル名/フォルダー名
をANSIの英数文字8文字限定にしますね。
つまり、MS-DOSと同じにします。そうすることによりUNIXとも互換性が取れますし、
汎用性が広がるんじゃないかと思います。
どこまで有効にするかを決めることが必要だと思います
仲澤@失業者さん、aetosさん、ITOさん、ご意見ありがとうございます。
やはり、APIなどで確実な変換や判定をというわけにはいかないのですね。
たしかに、ドライブ割り当てなどは考えていませんでしたし、
頭もかなり痛くなりまりました。
とりあえず、前述の絶対パス変換+小文字化した文字列をキーとするCMap管理で
アプリケーション独自のキャッシュ処理は実現できているのですが、
この方法では正しく動作しない実行環境もありうることがわかったので、
ITOさんの言われるように制限事項としてしまうか、
それともファイルパスをキーとする方法を根本的に再検討するべきか、
上に報告して検討してもらおうと思います。
ありがとうございます。
細かいことを言い出すと注意点は山のようにありますが...
ふつうに、ローカルパス(C:\...)やUNCパス(\\Server\)を扱うだけなら、
FindNextFile()系のAPIで変換すれば十分じゃないでしょうか?
相対パスも絶対パスに変換されますし、フォルダ区切りが / なら、\ に
変換してくれます。
MFCをお使いのようですので、APIをラッパしたCFileFindクラスがあります。
(例)カレントフォルダが C:\Test2\ のときに、C:\Test\Test.txtを検索
CFileFind Finder;
if(Finder.FindFile(../Test/Test.txt))
{
Finder.FindNextFile();
TRACE(Finder.GetFilePath()); // <- 絶対パスに変換済み
}
[出力結果]
c:\Test\Test.txt
もしくは、実際にファイルを開いて良いのなら、ファイルの排他処理で
同一ファイルを認識し、ファイルハンドルのマップにするという手も。
> ふつうに、ローカルパス(C:\...)やUNCパス(\\Server\)を扱うだけなら、
> FindNextFile()系のAPIで変換すれば十分じゃないでしょうか?
CFileFindはFindFirstFile()やFindNextFile()のようなAPIを呼ぶので、
存在しているものの名前としてOSが教えてくれるものでしょうから、
同じファイルに対しては同じ文字列になりそうですね。
こちらのほうが少ない処理で済みますし、
ファイルパスのCMapで行くとなったら、こちらに置き換えさせていただきます。
ありがとうございます。