プログレスバーのロジックについて

[戻る]
めあ 2011/12/21(水) 21:16:05
環境:VS2008、MFC

フォルダ選択をさせた後、
指定されたフォルダ内のファイル検索を行おうとしています。
検索中、時間がかかりそうなので検索している間にプログレスバーを表示しています。

そこで、プログレスバーの進め方のロジックについて質問があります。

普通ならば、フォルダ内のファイル数をCFileFindなどで回して
ファイル数を取得し、その数でプログレスバーのMAX値を設定すると思います。

しかし、ファイル数を取得するためだけに全ファイルを舐めるのは無駄ではないか?
ファイル検索だけなのに2倍の時間がかかるのではないか?
と思い、処理を軽くしてプログレスバーを実装する方法がないかと悩んでいます。

何か良い方法がありましたら、ご教授ください。

瀬戸っぷ [E-Mail] 2011/12/22(木) 00:28:19
>しかし、ファイル数を取得するためだけに全ファイルを舐めるのは無駄ではないか?

「ファイル数取得」の為でしたら、別にそのファイル自体にアクセスする必要はありませ
んよね?
CFileFindで対象拡張子だけで検索してファイル数をカウントすればいいだけかと。

>ファイル検索だけなのに2倍の時間がかかるのではないか?

ディレクトリエントリにアクセスするだけですからそんなに遅くはないはずですが…。
何故2倍なんでしょう???

対象となるファイルかはオープンしていくばくか読み込んでみないと判別できない。
とかいう状況なのでしょうか?
それなら、とりあえず全ファイルを対象として中身の確認はせずにファイル数をカウントし、
実際の処理で非対象ファイルと確定した時点でプログレスバーを進めればいいのではない
ですか?

tetrapod 2011/12/22(木) 07:20:58
プログレスバーを出す理由がハングアップしていない証明をユーザに見せるだけ、
であるなら、%表示する必要はなくて単にバーがぐるぐる回っているだけでもOK。
それならば100%を求めるために事前に何かする必要はない。
インストーラとかでもよく見るよね・・・

めあ 2011/12/26(月) 21:19:02
返信遅くなってすいません


>瀬戸っぷさん
実際にテストしてみたところ、以下のようになりました

※150GBほどのソースファイルがぎっしり詰まったドライブ
@ファイル数取得→15秒
Aファイル検索 →20秒

CFileFindで再帰呼び出しでディレクトリを舐めたところ、
このように時間がかかりました。
2倍とまではいかないまでも、結構倍近く時間がかかるみたいです
(マシンスペックによるのかもしれませんが)

プログレスバーを実装して、なおかつタイムアウト値も60秒程度に実装しようと考えて
いるので、できればAのファイル検索のみでバーを実装したいのです。
やはりプログレスバーを実装するならば時間がかかるのは免れないのでしょうか?


>tetrapodさん
回転アイコンなどにするならば楽だったのですが、
プログレスバーが一本表示されるようにしなければならないんです。
適当な場所で50%くらいまで進めて、処理が終わるまでずっとそこで待っている、
と言うのも考えたんですが、それだと処理時間が長い場合にフリーズしているようにも
見えてしまうので・・・

bun 2011/12/27(火) 14:23:01
1) 1回なめたときに、リストに保存してはどうか?
2) プログレスバーを2本にして、
   1本をフォルダ、もう一本をフォルダ内のファイルにしてはどうか?
   1本目のためにフォルダだけを総ナメなら対して時間は掛からない。
3) 1) 2) の合わせ技で、
   フォルダだけを1回なめて、その際にリストに保存してはどうか?

reopon2003 2011/12/27(火) 16:51:19
下の関数を用意すれば、2回検索しなくても良い・・・?
ファイル数を求めるのに必要な時間は
プログレスで性格に表現出来ないので、
『ファイルリストを取得中です。
  しばらくお待ちください・・・』
とか表示しておき、フリーズしていない
ことを明確にしたければ、検出したファイル名を
リアルタイムに表示してやれば良いと思います。

DWORD getFileList(CStringArray& sa)
{
    CFileFind finder;
    sa.RemoveAll();
    BOOL bWorking = finder.FindFile("C:\\*.*");
    while (bWorking)
    {
        bWorking = finder.FindNextFile();
        sa.Add(finder.GetFilePath());  //検索したファイルの完全パスを保存します。
    }
    return (DWORD)sa.GetSize()
}

aetos 2011/12/27(火) 17:03:06
プログレスバーについては、PBS_MARQUEE スタイルについて調べてみてください。

PATIO 2011/12/27(火) 17:15:54
基本的に全体量に対しての%でプログレスバーを勧める方式でやるのであれば、
検索前に数のカウントをするのは避けられないと思います。
この部分はどう考えても無理な相談かと。

マーキーみたいな表示をすれば止まっていないよと言うのを見せられそうですが、
VC++2008、MFCでどうすればマーキー表示になるのかはわからないです。
C#だと簡単なんですけどねぇ。

StepItで回し続ければそれっぽい表示にはなりますけれど、
マーキー表示とは違う感じですしねぇ。
(0%から100%まで行くとまた0%から始まるのをぐるぐる繰り返す感じです)

めあ 2011/12/29(木) 03:02:01
[[解決]]
>bunさん、reopon2003さん
リストに保存するやり方は、ファイル数が多いとやたらメモリを食ってしまいそうで
あまりやりたくないんですよね・・・
最近の高スペックなマシンなら問題なさそうな気はしますが


>aetosさん
PBS_MARQUEE、良いですね!
自分の要望とは少し違いますが、これならアリかなという気もしてきました


>PATIOさん
http://thunor.sblo.jp/article/27448868.html
ここのサイトを参考に、マルチスレッドに記述で簡単に実装できました

繰り返し回すバーも、候補に入れていたのですが
マーキー表示のほうが良さそうなので、これでいくかもしれません



とりあえず解決としておきます
みなさんありがとうございました!

古いスレッドには追加発言できません。