CopyFileExについて

[戻る]
YORK 2009/10/07(水) 17:26:11
よろしくお願い致します。
VC2003、MFCを使用してアプリを開発しています。

LAN上のHDDにファイルをコピーする処理をCopyFileExを使って行っています。
例えば、ファイルコピー中にネットワークのトラフィックが溜まって待ち状態に
なった場合、CopyFileExはエラーを返してくるのでしょうか?

エラーを返さずにCopyFileEx内で待ち状態が解決されるまで待ってくれる場合、
・タイムアウトはあるのか?
エラーを返してくる場合、
・そのエラー値は何なのか?
・その後リトライするにはもう一度CopyFileExを呼び出すしか方法がないのか?
上記のことが知りたいのですが、ご存じの方いらっしゃいますか?

実際に試してみようにもテスト環境が作れず
経験がある方がいましたらご教授願いたいと思います。

お願いします。

tetrapod 2009/10/07(水) 19:26:38
> ファイルコピー中にネットワークのトラフィックが溜まって
> 待ち状態になった場合
日本語の意味がわからんのだが、具体的にどういう状況を想定しているのだろう?

ネットワーク負荷が上がって LAN HDD の内部転送速度より遅くなった状況?
それなら単にゆっくりコピーするだけのこと。
http://msdn.microsoft.com/ja-jp/library/cc429187.aspx
タイムアウトするなど書いてないぞ。

YORK 2009/10/07(水) 20:16:28
>日本語の意味がわからんのだが、具体的にどういう状況を想定しているのだろう?
ネットワークの負荷が上がって、
まったくデータが転送されなくなる状況(←あるのかな?)
があったとしたら、という話です。

そんな状況が物理的にあり得なければ別に良いのですが、、。

tetrapod 2009/10/07(水) 22:08:41
まともな LAN ハード+ドライバならそういうことはありえない。

まともでないならありうるわけで、コピー中に
・LAN ケーブル引っこ抜いてみるとか
・LAN HDD の電源切るとか
・LAN HUB の電源切るとか
・(10BASE-2 なら) 終端抵抗はずしてみるとか
・その状態から正常状態に復帰させてみるとか
そういう「ありうる」状況のほうを心配するほうが有意義だと思うぞ

bun 2009/10/08(木) 09:31:57
あくまで私の意見ですが、全てのエラーパターンを考慮するなんて、
  ・あなたがCopyFileEx()関数の設計者である
  ・全てのエラーパターンがMSDNに列挙されている
  ・  :
など、期待するべくもない状況下でしかあり得ない気がします。
それに、たとえ現段階でそれが分かったとしても、Windows7ではエラーパターン
が増えているかもしれません。

であるなら、そういうことはOS任せにしたほうが良い気がします。
CopyFileEx()がエラーした場合、GetLastError()で詳細情報がとれると言ってい
るわけですから、FormatMessage()でエラーメッセージに変換して、メッセージ
ボックスなりで表示する。
これなら、OSの仕様がどう変わろうと問題が起きないわけで、それで十分ではな
いでしょうか。

もう少し親切にするなら、
エラーメッセージ表示後にリトライ可能な仕組みにすればよいです。
(例) メッセージ内容が「排他オープン中のファイルあり」とかなら、
     ユーザにそのファイルを閉じてもらった上で、リトライしてもらう
      ※ コールバック関数でPROGRESS_CONTINUEを返せばよいのかな?

ITO 2009/10/08(木) 10:42:47
http://msdn.microsoft.com/ja-jp/library/cc429187.aspx
ここを見ると中断することは出来そうですね。
 アドレスはtetrapodさんが先に掲示していましたね。
スレッドで実行して、
  タイムアウトかどうかはソフトで上で判断して
    ・コールバック関数内でキャンセルさせるのか?
    ・それとも、コールバック関数内でキャンセルのフラグと立てて、
      親スレッドでキャンセルするのか?
   僕もこの関数を使ったこのないので詳しく分からないのですが、やりようは
  上記の2点ぐらいが考えられますね。

YORKさんは、ブラウザー上のダウンロードのタイムアウトエラーみたいなのを実現
 させたいのですよね?

YORK 2009/10/08(木) 11:23:35
[[解決]]
皆様、ありがとうございます。

失敗したら、エラーコード関係なしにリトライするようにします。

CopyFileExのコールバックではエラーを取得できないので
CopyFileExの第6引数にCOPY_FILE_RESTARTABLEを指定して、
FALSEが返ってきたら、リトライをする(タイムアウトももうける)
ようにします。

的をえない質問ですみませんでした。
ありがとうございました。

tetrapod 2009/10/09(金) 09:15:06
勝手にリトライする、ねぇ・・・やめとくほうを推奨する。

・コピー先 HDD がいっぱいになったのにコピーしつづけようとする
・コピー先 HDD がクラッシュしたのに r)
・ネットワーク経路の途中で断線しているのに r)
など、人間の介入なしに復旧がありえない状況であっても永遠にリトライするんだが

仕様考察が甘いんぢゃないのかな。

無人状態でのバックアップ目的とかなら余計に
「エラーをきっちり表示し中断する」
ほうが、翌日のバックアップ実施までに対策がきっちり取れて望ましいと思うぞ。

YORK 2009/10/09(金) 13:01:58
>仕様考察が甘いんぢゃないのかな。
>無人状態でのバックアップ目的とかなら余計に
>「エラーをきっちり表示し中断する」
>ほうが、翌日のバックアップ実施までに対策がきっちり取れて望ましいと思うぞ。

ご忠告ありがとうございます。
永遠にリトライはしません、それが仕様としてとおるわけもありません。
エラーの場合、一定時間待って、リトライを1度する、というようにします。

ITO 2009/10/09(金) 13:02:36
> 無人状態でのバックアップ目的とかなら余計に
> 「エラーをきっちり表示し中断する」
> ほうが、翌日のバックアップ実施までに対策がきっちり取れて望ましいと思うぞ。
うーん、
 確かに無人状態の場合は、リトライしないでエラー終了するのがいいですね。
しかし、
 流れ作業中の場合、
  バックアップした後データをシーケンサ等に渡し、作業が継続される場合は変わり
ますね。

まず、
> ・コピー先 HDD がいっぱいになったのにコピーしつづけようとする
 1.HDD がいっぱいになった時点で停止する。
 2.シーケンサー側でアラーム出力作業員呼び出し
 3.HD修復
 4.アラームリセット、再開。
ですね。

>・コピー先 HDD がクラッシュしたのに r)
> 1.HDD がいっぱいになった時点で停止する。
これをするので実際はありえないと解釈する。
どうしても該当される場合、
アラーム出力→完全停止→再開なし


>・ネットワーク経路の途中で断線しているのに r)
素人の作業員が関与しているからケーブルが断線するのは当たり前と解釈する。
修復されたら勝手に再開してくれないと困る。→ 要リトライ機能
修復作業に手間取っているのにリトライが続いている。
  →止まってほしい。→要タイムアウト機能
ですね。

中には、どうして断線したのか、原因と対策をしたい。
という顧客もいます。
  勝手にリトライしたくない→要マニュアルリトライ機能。 

リトライするかしないかは、顧客の要望によって変わると思います。

 

ITO 2009/10/09(金) 13:40:14
あ!、追加です。

> ・コピー先 HDD がいっぱいになったのにコピーしつづけようとする
USBのHDDに変更して続行したいという要望も考えられるので、
保存先が変更できるようにしておいたほうがいいですね。

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