毎度お世話になっております。
まず環境
VisualC++2005
Win32 PlatformSDK
WindowsXP/2000
現在ファイルをコピーする関数を作成しているのですが、単純なCopyFileを使ったものではなく、以
下のような特徴を持っています。
コピーの前にコピー元と先でファイルサイズと内容を比較し、一致すればコピーせずに終了、一致し
なければ、実際にコピーするかメッセージボックス等でユーザに問い合わせる。
「はい」を選択した場合コピーを開始し、プログレスバーなどで進捗を表示。
という感じです。
しかし大容量のファイルをコピーする際に、ファイルの比較に時間がかかりフリーズに近い状態に
陥ってしまいます。実際のコピー処理辞退はプログラスバーを使っているので大丈夫なのです
が、ファイルの比較になるべくプログレスバーは使いたくありません。(めんどくさいことも含め)
高速化を含めなにかいい方法はないでしょうか?
ちなみに現在は、比較に以下のようなReadFile等でちょびちょび読み込みながら比較を行っていま
す。最初はファイルのデータを全部一気に読み込んで比較していたのですが、メモリ不足で遅かった
ので、ちょびちょびに変えました。
if( size1[0] == size2[0] ){ >// サイズが一致したなら内容比較
>// 1024 : ちょびちょび読みつつ比較
int CmpSize = 1024;
if( size1[0] > (1024 * 1024 * 10) ) { >// 10M以上(たぶん
>// ファイルサイズが大きい場合はもう少し多めに
CmpSize = 1024 * 1024;
}
p1 = (BYTE*)malloc( CmpSize );
p2 = (BYTE*)malloc( CmpSize );
if( p2 )
{
while(1)
{
DWORD _size1, _size2;
>// ちょびっと読み込む
int success = ReadFile( hFile1, p1, CmpSize, &_size1, NULL );
if( success ) {
success = ReadFile( hFile2, p2, CmpSize, &_size2, NULL
);
}
if( !success ) { >// 読み込みエラー (基本的にない)
cmp_ret = -4;
break;
}
if( _size1 == 0 ) { >// 終端
cmp_ret = 0; >// 一致を戻り値にセット
break;
}
if( (_size1 != _size2) || memcmp( p1, p2, _size1 ) != 0 ) { >//
内容が一致しなければ
cmp_ret = 1; >// 不一致を戻り値にセット
break;
}
}
}
}
よろしくおねがいします。
で、今のやり方に不満があるのでしょうか?
>で、今のやり方に不満があるのでしょうか?
比較で時間がかかり、フリーズした感じになるのを何とかしたい。
なんとかならないなら、せめて比較の時間だけでも短縮させたい。
という感じです。
↑の比較プログラムは何も考えず適当に作ったのでたぶん遅い。
現在150M程度のファイル同士(同じサイズ)でテストしているのですが、
コピー処理(SHFileOperation)は15秒程度で終わるのに対し、
上の比較では、60秒以上かかります。
>で、今のやり方に不満があるのでしょうか?
比較で時間がかかり、フリーズした感じになるのを何とかしたい。
なんとかならないなら、せめて比較の時間だけでも短縮させたい。
という感じです。
↑の比較プログラムは何も考えず適当に作ったのでたぶん遅い。
現在150M程度のファイル同士(同じサイズ)でテストしているのですが、
コピー処理(SHFileOperation)は15秒程度で終わるのに対し、
上の比較では、60秒以上かかります。
1- CmpSizeをもっと大きくすれば?
2- ループの合間にメッセージ・ポンプを押し込めば?
3- スレッドを分離すれば?
※ 2,3 は速くするんじゃなく、フリーズ除けですが。
επιστημηさんありがとうございます。
> 2- ループの合間にメッセージ・ポンプを押し込めば?
> 3- スレッドを分離すれば?
なるほど。
この間にプログレスバーみたいなので進捗を表示すればいいわけですね。
まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂時計
カーソルとかにするのがいいんですかね・・・・
> 1- CmpSizeをもっと大きくすれば?
10Mにしてみましたが、多少速くなる程度でしたね。
っていうか実際のコピー処理より前処理の比較の方が時間がかかるのが許せないですね。やっぱり
ループになにかしらの不具合があるのかな?
> 比較で時間がかかり、フリーズした感じになるのを何とかしたい。
「フリーズ」って言葉はちょっと違かったかも・・・
比較処理の「間」のことです。
フリーズしなくても、変な「間」があると、やっぱり使ってる人は ん? って思いますし。
> 比較で時間がかかり、フリーズした感じになるのを何とかしたい。
「フリーズ」って言葉はちょっと違かったかも・・・
比較処理の「間」のことです。
フリーズしなくても、変な「間」があると、やっぱり使ってる人は ん? って思いますし。
> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂
時計カーソルとかにするのがいいんですかね・・・・
それはアナタが(動きを見ながら)決めること。
ちょっと計測してみたのですが、
ReadFileが重いみたいです。
2回のReadFileと、memcmpの処理時間をQueryPerformanceCounterで計測してみました。
CmpSize : 1M (1024 * 1024)
回数:5
-------------------------
ReadFile : 1924323
Comp : 13604
ReadFile : 4301359
Comp : 13067
ReadFile : 22136
Comp : 13648
ReadFile : 21126
Comp : 13242
ReadFile : 1918485
Comp : 13509
--------------------------
なんかたまに早い時もありますね。
コピー処理はなんであんなに早いんですかね?(SHFileOperation内部ではReadFileを使ってない
のかな?)
ReadFileについて調べることにします。
ありがとうございました。
※もう少し情報ほしいので、まだ解決にチェックは付けません。
ちょっと計測してみたのですが、
ReadFileが重いみたいです。
2回のReadFileと、memcmpの処理時間をQueryPerformanceCounterで計測してみました。
CmpSize : 1M (1024 * 1024)
回数:5
-------------------------
ReadFile : 1924323
Comp : 13604
ReadFile : 4301359
Comp : 13067
ReadFile : 22136
Comp : 13648
ReadFile : 21126
Comp : 13242
ReadFile : 1918485
Comp : 13509
--------------------------
なんかたまに早い時もありますね。
コピー処理はなんであんなに早いんですかね?(SHFileOperation内部ではReadFileを使ってない
のかな?)
ReadFileについて調べることにします。
ありがとうございました。
※もう少し情報ほしいので、まだ解決にチェックは付けません。
申し訳ありません。
二回投稿してしまったみたいです。
>> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂
> 時計カーソルとかにするのがいいんですかね・・・・
> それはアナタが(動きを見ながら)決めること。
その方法も含めて質問しています。
よろしくおねがいします。
>>> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなん
で、砂
>> 時計カーソルとかにするのがいいんですかね・・・・
>> それはアナタが(動きを見ながら)決めること。
> その方法も含めて質問しています。
は?
プログレスバー使うのが大げさかどうか訊かれても、そんなもんcase-by-caseでしょうに。
その待ちが利用者に不安/不満を与えるのであれば、それを軽減する策を講じるってだけ。
# それとも 絶対プログレスバーを表示せよ!って僕が書いたら従います?
すいません。
質問が漠然としていました。
> 高速化を含めなにかいい方法はないでしょうか?
ReadFileが遅いことがわかったので、後は自分で調べてみます。
2,3日してまた解決しなかったらまた質問させていただきます。
あとは、最悪、10M以上はコピーできないなどの制限を付けてみるという方法もありかな、なんて
思いました。
ありがとうございました。