CFileFindで*.htmを検索したところ、.htmlのファイルも引っかかってしまいました。
「前方一致だったか?」と疑問に思い、*.hで検索してみると、
.htmも.htmlも引っかかりませんでした。
調べてみたところ、Windowsは8.3形式のショートファイル名も検索していて、
.htmlも8.3形式では.htmのため引っかかってしまうようなのですが、
ここでいくつか疑問があります。
このような動作は正直迷惑で、今回の例では*.htmのみを探したいのですが、
ロングファイル名のみを検索対象とすることはできないのでしょうか。
見つかったファイルの拡張子を毎回判定していくしかないのでしょうか。
ショートファイル名の拡張子は、
必ずロングファイル名の拡張子の前3文字になることは決まっているのでしょうか。
たとえば、.htmlがショートファイル名で.hに置き換わることはあり得るのでしょうか。
もしそうだとすると、2文字以下の拡張子も、同じように毎回判定するべきなのでしょうか。
Windows のファイル検索 API がショートファイル名を見てしまうのは仕様らしい。
一番簡単な対処はやはり、検索で得たファイル名の 拡張子 部分を再検査、かな。
状況が許せばこんな対策も
http://www.atmarkit.co.jp/fwin2k/win2ktips/1200disable83/disable83.html
> 必ずロングファイル名の拡張子の前3文字になることは決まっているのでしょうか。
公式文書は見つけられんかった。そもそも NTFS の仕様は非公開。
もっというなら CIFS で接続したネットワークドライブの先の OS は Windows とは限らず
Linux かもしれないし、誰かが独自に作ったオレオレ OS かもしれないわけで、
その意味で「何がどうなるかはわからない」と言っていいだろう。
ただまあショートファイル名の存在意義が MS-DOS との互換性、であるわけで
拡張子が3文字以下ならそのままになる、というのが [ありうる実装] と俺は思う。
でもさ、プログラムの実装として
・拡張子4文字以上なら検索結果を再検査する
・拡張子の文字数に関係なく検索結果を再検査する
だと、俺は後者のほうが簡単っぽく思うのだが、どうかな?
情報ありがとうございます。
Windowsでは、特定の拡張子のファイルを検索する際には、
*.htmや*.txtなどで指定しても厳密な検索はできず(*.hや*.csなどは微妙)、
見つかったファイルを自前で判定し直さなければいけないということですね。
その割には、CFileFindには、GetFileName()やGetFileTitle()はあるのに、
拡張子のみを取得するものは無いのですよね。
もちろん、splitpath()やPathFindExtension()などで取れるのはわかっていますが、
自前で判定し直す必要があるのなら、CFileFind自体に入れておいてくれよと思います。
CFileFind::IsDirectory()などの判定は行ってきましたが、
ファイル名が検索で指定したものと違うかなんて疑っていませんでした。
今まで作成したプログラムが怖くなってきました。