ファイル名の取得に時間がかかる

解決


まこと  2008-12-23 19:50:46  No: 32954

いつもお世話になります。

  Windows98などでは、関連付けでファイルを開く場合、ParamStrに格納
されるファイル名が、短いファイル名になってしまっています。
  その短いファイル名を長いファイル名に直すため、以下のような関数を
使用しています。
  これは、ローカルハードディスクだと一瞬で取得できるのですが、ネット
ワーク上にあるファイルだと、10秒近くも時間がかかってしまいます。
なぜ時間がかかるのか、よく分かっていません。(正常にファイル名を取得
出来てはいるのです。)
  遅い理由についてご指摘いただけると幸いです。

  ※ファイル名のサンプル  「\\1600-11\新規フォルダ\一時保存\Macro.txt」  
  ※環境はWindowsXP + Delphi 6 Personal です。

-------------------------------------------------
function TForm1.GetPathName(FileName: String): String;
var
  SearchRec: TSearchRec;
begin
  Result := FileName;
  if (Copy(FileName, Length(FileName), 1) = '\') then
    Result := Copy(FileName, 1, Length(FileName) - 1);
  // ↓ここの判定を、if (Result = '\') then
  // ↓などとしてもうまく行かなかったです。
  if (Length(Result) = 2) and (Copy(Result, 2, 1) = ':') then exit;
  if FindFirst(Result, faAnyFile, SearchRec) = 0 then
    Result := GetPathName(ExtractFilePath(Result)) + '\' + SearchRec.Name;
  FindClose(SearchRec);
end;


Mr.XRAY  URL  2008-12-23 23:26:26  No: 32955

>※環境はWindowsXP + Delphi 6 Personal です。

プレゼンテーション資料などもそうですが,箇条書きだと分かりやすいのですね,
質問される方が箇条書きするのはちょっと大変ですが,読むほうは楽です.
動作を順に追っていけますから.

1. WindowsXP + Delphi6 で作成したあるプログラムをXP上で起動する
    ここが間違って理解している? Windows98上で実行するのだろうか?
2. そのプログラムのあるボタンをクリックすると,
3. ネットワーク上のWindows98のあるファイルを関連づけ(拡張子?)で起動する
4. で「ParamStrに格納」する? される? というのは?
5. 短いファイル名になってしまう.どこのファイル名?

さて,どういう動作仕様なんでしょう.
だいぶ画面で読みながら考えたのですが.理解できませんでした.
私の理解力では(笑).
また,動作仕様がわかっても適切なアドバイスはできないかも知れませんが.


igy  2008-12-24 05:55:27  No: 32956

>遅い理由についてご指摘いただけると幸いです。

理由はわかりませんが、

>function TForm1.GetPathName(FileName: String): String;

再帰を使っているようですが、
・関数内のどの部分で遅くなってますか?
・再帰でGetPathName()が実行される時、引数がどの値のときでも遅くなってますか?
・特定のネットワーク上PCのファイルでのみ遅くなりますか?
  それともネットワーク上の別のPCのファイルでも遅くなりますか?


wheel  2008-12-24 10:03:10  No: 32957

GetLongPathNameじゃ駄目なんでしょうか。95以前だと使えないから?

その方式だと「\\1600-11\新規フォルダ\一時保存\Macro.txt」
「\\1600-11\新規フォルダ\一時保存」「\\1600-11\新規フォルダ」
「\\1600-11」と何度もネットワークフォルダの検索が入るので
それで時間がかかるのかもしれません。
あと、大した問題ではないかもしれませんが
そのアルゴリズムだと最後に「\」を探しに行ってしまいますよね?

ついでに、末尾の「\」を削るのはExcludeTrailingPathDelimiterでできますよ。
(あるいは最初からExtractFilePathではなくDirの方を使っておくとか)


まこと  2009-01-15 07:01:41  No: 32958

いろいろ助言いただいたのに長く書き込めず申し訳ありません。
いろいろ試行錯誤していたのですが、私自身、ネットワークドライブの
ドライブ名というものがよく分かっていなかったので、間違ってしまって
いたようです。

ExtractFileDriveで確認したところ、ドライブ名は
\\1600-11
ではなく
\\1600-11\新規フォルダ
と出ており、ここで自分の思い込みに気づきました。
これを元に、関数を修正してみたいと思います。

>Mr.XRAY様
・質問の書き方が分かりにくくてすみませんでした。
  今後は改善を図りたいと思います。

>igy様
・どの部分で遅くなるか、については、関数内にShowMessage
  を組み込むなどして、処理時間などを調べていたのですが、
  \\1600-11\新規フォルダ
  の部分で引っかかっていたようで、ShowMessageが出なかったりして、
  うまく調べられていませんでした。
  (当時はなぜでないかすらよく分かっていませんでした。)

>wheel様
・ExcludeTrailingPathDelimiterについては、関数に導入させて
  いただきます。関数が簡単になりました。どうもありがとうございます。
・GetLongPathNameについては、簡単に使えてよいのですが、一応どの
  OSでも使える、という前提は崩したくないので、当面はこの自作
  関数で行きたいと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加