このようなJavaに関するいくつかの質問がありますが、誰も私が見つけた回答を受け入れておらず、私の状況はもう少し具体的です。私は、ファイルを1つずつ処理するプログラムを持っています。時には、ファイルが私のプログラムに見えるようになってから、プログラムが数秒間それらを落とすことによって、ファイルが使用中にロックされたままになることがあります。私はそのプログラムを支配していません。私のプログラムでは、プログラムがそのファイルを読み込もうとしているときにファイルが使用中であれば、すでにエラー処理をしています。ファイルが完全にスキップされます。私が実装したいのは、ファイルが数秒後にロック解除されるかどうかを調べるための再試行スキームです。ここでの別の質問では、FileUtils.touch()
を使用するよう提案しました。プロジェクトで既にFileUtilsを使用しているので便利です。 javadocによると、FileUtils.touch()
はファイルが別のプロセスで使用されている場合はIOException
となります。いいね。しかし、私が言いました答えの下のコメントの1つは、何の説明もなしに競合状態を警告しました。ここで私が導入を検討していたコードです:ファイルロックがリリースされるのを待っています
// Implementing Sason's suggestion
int retries = 0;
while (retries < MAX_RETRIES) {
try {
processFile(file);
} catch (IOException ioe) {
// Assumes this is a file in use exception... bad thing?
log.warn("File is in use. Waiting 1 second to retry.");
retries++;
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
log.warn("Thread interrupted while waiting for file lock to clear.");
break;
}
}
}
私は、ファイルがFileUtils.touch(間再びロックになることができることを実現)とprocessFile()
メソッド呼び出しは(と私はそれが競合状態が中程度警告していると推定します私が見つけた受け入れられない答え)でも、それは問題ありません。 processFile()
メソッドは、現在のようにロックエラーを処理します。この場合、ファイルが別のプロセスによって開かれても問題ありませんが、ロックすることはできません。
また、ファイルが1,2秒後にロック解除されることがありますが、ファイルを削除するプログラムによってロックが無期限に保持される場合もあります。また、同じファイルを再処理しようとすると、再試行が終わった後にファイルを処理できなかったときに送信者に通知できるようにする必要があります。
ここに何か不足していますか?これを行うにはより良い/より安全な方法がありますか?
'touch()'は、ファイルが開いているかどうかをテストする信頼できる方法です。特定のプロセスがファイルを書き込んでいる特定のシステムで動作するかもしれませんが、それは問題ありませんが、コードをどこか別の場所で実行したり、ライターを変更した場合は、再テストして動作することを確認する必要があります。これを行う正しい方法は 'FileLock'ですが、それは書き込みプログラムが基礎となるファイルシステムのロック機構を使うことを必要とします。 – erickson
私は私の質問でもっとはっきりしていたはずです。ファイルがロックされていない別のプロセス(たとえば、NotePad ++など)でファイルが開いている場合は、問題ありません。 'processFile()'がファイルをロックしようとするためロックできません。私は 'FileLock'についてあなたの意見を見ていますが、あなたはかなりリファクタリングを必要とすることに間違いありません。私は 'touch()'は、別のプログラムがファイルをオープンしているがロックされていないかもしれないという同じ注意書きでクロスプラットフォームで動作すると思う。 –