Java ファイルメソッド「canWrite()」はロックをサポートできますか?

StackOverflow https://stackoverflow.com/questions/122282

  •  02-07-2019
  •  | 
  •  

質問

フォルダー内の受信 XML ファイルを監視する Java アプリケーションがあります。新しいファイルが検出された場合、そのファイルが現在更新されておらず、閉じられていることをテストする必要があります。私の考えは使用することです File.canWrite() これをテストするために。これを行うことに問題はありますか?これはファイルが完全に書き込まれたことをテストする良い方法ですか?

私が考えている他のアイデアは次のとおりです。

  • 着信XMLファイルを解析し、クロージングタグがあることをテストします。
  • EoF 文字を確認します。

これらの方法がすべてのシナリオに対応できるかどうかはわかりません。

役に立ちましたか?

解決

いいえ、canWrite はこの目的には適していません。一般に、別のプロセスが書き込みを行っている場合でも、ファイルは書き込み可能です。

ロックを調整するには、より高いレベルのプロトコルが必要です。このコードを単一のプラットフォームで使用する予定がある場合は、次のようにすることができます。 NIO の FileLock 機能. 。ただし、ドキュメントを注意深く読み、多くのプラットフォームではロックは単なる勧告であることに注意してください。

もう 1 つの方法は、1 つのプロセスにそのプロセスが認識できない名前でファイルを書き込み、書き込みが完了したときにファイルの名前を認識可能な名前に変更することです。ほとんどのプラットフォームでは、ソースと宛先が同じファイル システム ボリュームである場合、名前変更操作はアトミックです。名前の変更では、別のファイル拡張子が使用される場合や、ファイルが 1 つのディレクトリから別のディレクトリ (同じボリューム上) に移動される場合もあります。

この場合、XML のみを使用して作業しているため、終了タグを探すことはできますが、確実ではありません。最終マークアップの後にコメントがある場合や、ライターが、あるいは単に有効な XML を記述していない場合はどうなるでしょうか?

EOF の意志を探しています ない 仕事。ライターがファイルを開いたばかりでまだ何も書き込んでいない場合でも、常に EOF が存在します。そうでない場合、最も簡単な方法は、ファイルが表示されるとすぐにリーダーが解析を開始できるようにすることです。ライターがファイルを閉じるまでブロックされるだけです。しかし、ファイルシステムはこのようには機能しません。たとえ現在何らかのプロセスがファイルを移動しているとしても、すべてのファイルには終わりがあります。

他のヒント

さらに、チェックを行ってから書き込みを行うと、競合状態が発生します。状態はチェックと書き込みの間で変化する可能性があります。必要なことを実行し、エラーを適切に処理することが最善の場合もあります。おそらく、フォールバック遅延時間が増加した n 回の再試行メカニズムが考えられます。

またはテストを再定義します。この場合、ファイルを処理する前に、一定期間にわたってファイルサイズが変化していないことをテストできる可能性があります。

もう 1 つのオプションは、コードを 2 つに分割することです。完成したファイルをメイン コードが処理する別のディレクトリに移動する役割を担う別のスレッド (おそらく Quartz タスク) を設けることもできます。

Windowsで動作するように見えることの1つは、これが問題のファイルを表すファイル()オブジェクトを作成することです(完全なファイル名でコンストラクターを使用) - 同じ方法で2番目の同一のファイルオブジェクトを作成します。- firstFile.renameTo(secondFile) を試してください

このダミーの名前変更演習は、別のアプリで編集用に開かれていないファイル (私は Word でテストしました) では成功するようですが、ファイルが開いている場合は失敗します。

そして、新しいファイル名 = 古いファイル名であるため、他の作業は作成されません。

私の知る限り、別のプロセスが現在 Java からのファイルへのオープン ハンドルを持っているかどうかを知る方法はありません。1 つのオプションは、 ファイルロック 新しい io のクラス。これはすべてのプラットフォームでサポートされているわけではありませんが、ファイルがローカルにあり、ファイルを書き込むプロセスが連携する場合、ロックをサポートするすべてのプラットフォームで機能するはずです。

リーダーとライターの両方を制御する場合、ロック手法として考えられるのは、ロックを作成することです。 ディレクトリ -- これは通常、読み取りおよび書き込みプロセス期間中のアトミック操作です。このタイプのアプローチを採用する場合は、ロック ディレクトリの「ハング」を引き起こすプロセスの潜在的な障害を管理する必要があります。

Cheekysoft が述べたように、ファイルはアトミックではないため、ロックには適していません。

ライターを制御しない場合 (たとえば、ライターが FTP デーモンによって生成されている場合)、名前変更手法または期間遅延手法が最適なオプションです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top