ファイルパス文字列をキーにしたい – プログラミング – Home

ファイルパス文字列をキーにしたい
 
通知
すべてクリア

[解決済] ファイルパス文字列をキーにしたい


亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

VC2005 MFC です。

同じ場所を指している、異なるファイルパス文字列に対して
必ず同じ文字列が返ってくるようにする方法はありますでしょうか。

ファイルパス名の文字列(場所)をキーとしたCMapを作りたいのですが、
大文字/小文字や相対/絶対などいろいろな表記方法があるので、
同じ場所を指している2つのキーが作られてしまわないようにしたいです。

現在は、渡されたファイルパス名が絶対パスだろうが相対パスだろうが
GetCurrentDirectory()とPathAppend()を使って必ず絶対パスに変換し、
PathCanonicalize()を使って無駄な部分を省き、
最後に小文字に変換した文字列をキーとしてみましたが、
これでも同じ場所を指しているのに異なるキーになってしまう可能性は
ありますでしょうか?
もしくは、もっと簡単に作成できる方法はありますでしょうか?


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

「異なる絶対パスが物理的に同じ場所を指し示す可能性はあるのか」
という質問になるかと思いますが、それは「ありえる」ではないでしょうか。
1.あるフォルダをドライブに読み替えている場合。
2.ネットワークドライブを割り当てている場合。
などが想像できますが、どうでしょう。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

この辺読むと頭が痛くなると思います。
http://www.ipa.go.jp/security/awareness/vendor/programming/b08_01.html


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> GetCurrentDirectory()とPathAppend()を使って必ず絶対パスに変換し、

だったら GetFullPathName を使うべきです。

> PathCanonicalize()を使って無駄な部分を省き、

が前述の IPA のサイトに書いてあるようなのにどこまで対応しているかですね。

あとは、ハードリンクとかジャンクションとかをどう扱うかとか。
あとはあとは、大文字と小文字が非可逆変換になっちゃう文字もあったような。ファイル
パスには Unicode を使えますので、日本語と英語アルファベットだけ考えていていいの
かどうかわかりません。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

 私の場合なら、客先との要求にもよりますが、ファイル名/フォルダー名
をANSIの英数文字8文字限定にしますね。
 つまり、MS-DOSと同じにします。そうすることによりUNIXとも互換性が取れますし、
汎用性が広がるんじゃないかと思います。
 どこまで有効にするかを決めることが必要だと思います


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

仲澤@失業者さん、aetosさん、ITOさん、ご意見ありがとうございます。
やはり、APIなどで確実な変換や判定をというわけにはいかないのですね。
たしかに、ドライブ割り当てなどは考えていませんでしたし、
頭もかなり痛くなりまりました。

とりあえず、前述の絶対パス変換+小文字化した文字列をキーとするCMap管理で
アプリケーション独自のキャッシュ処理は実現できているのですが、
この方法では正しく動作しない実行環境もありうることがわかったので、
ITOさんの言われるように制限事項としてしまうか、
それともファイルパスをキーとする方法を根本的に再検討するべきか、
上に報告して検討してもらおうと思います。
ありがとうございます。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

細かいことを言い出すと注意点は山のようにありますが...

ふつうに、ローカルパス(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


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

もしくは、実際にファイルを開いて良いのなら、ファイルの排他処理で
同一ファイルを認識し、ファイルハンドルのマップにするという手も。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

> ふつうに、ローカルパス(C:\...)やUNCパス(\\Server\)を扱うだけなら、
> FindNextFile()系のAPIで変換すれば十分じゃないでしょうか?

CFileFindはFindFirstFile()やFindNextFile()のようなAPIを呼ぶので、
存在しているものの名前としてOSが教えてくれるものでしょうから、
同じファイルに対しては同じ文字列になりそうですね。

こちらのほうが少ない処理で済みますし、
ファイルパスのCMapで行くとなったら、こちらに置き換えさせていただきます。
ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました