失敗後に再試行する場合は、そのコードをループ内に配置する必要があります。たとえば、次のようなものです。
boolean done = false;
while (!done) {
try {
...
done = true;
} catch (...) {
}
}
(do-while はもう少しエレガントなソリューションです。)
Exception
ただし、このコンテキストでキャッチするのは悪い習慣です。発生すると予想される例外 (例: IOException
) だけでなくNullPointerException
、プログラムのバグの兆候である予期しない例外などもキャッチします。
ベスト プラクティスは、予期している (そして処理できる) 例外をキャッチし、他の例外を伝播できるようにすることです。あなたの特定のケースでは、キャッチFileNotFoundException
で十分です。(これはScanner(File)
コンストラクターが宣言するものです。) 入力に a を使用していない場合は、代わりScanner
に catch が必要になる場合があります。IOException
上位投票の回答の重大な間違いを修正する必要があります。
do {
....
} while (!file.exists());
ファイルが存在することをテストするだけでは不十分なため、これは正しくありません。
- ファイルは存在する可能性がありますが、ユーザーにはそれを読み取る権限がありません。
- ファイルが存在する可能性がありますが、ディレクトリである場合、
- ファイルが存在する可能性がありますが、ハードディスクのエラーなどにより開くことができません
exists()
テストが成功してから次にファイルを開こうとするまでの間に、ファイルが削除/リンク解除/名前変更される可能性があります。
ご了承ください:
File.exists()
ファイル システム オブジェクトが指定されたパスに存在することのみをテストします。実際にファイルであること、またはユーザーが読み取りまたは書き込みアクセス権を持っていることはテストしません。
- ハード ディスク エラーやネットワーク ドライブ エラーなどによって I/O 操作が失敗するかどうかをテストする方法はありません。
- オープンと削除済み/リンク解除済み/名前変更済みの競合状態に対する解決策はありません。通常の使用ではめったに発生しませんが、問題のファイルがセキュリティ クリティカルである場合、この種のバグが標的になる可能性があります。
正しいアプローチは、単にファイルを開こうとし、それが発生したIOException
場合にキャッチして処理することです。それはよりシンプルでより堅牢で、おそらくより高速です。そして、「通常のフロー制御」に例外を使用すべきではないと言う人にとって、これは通常のフロー制御ではありません...