14

私の Java アプリケーション (かなりの量のコード) は、多くのファイル操作を行います。アプリケーションのある時点で、ある場所から別の場所にファイルを移動する必要があり、そのためにFiles.moveJDK7 のメソッドを使用しています。

これを実行しようとすると、ファイルが使用中であるというエラーが表示されます。このリソースをロックしているのは私のコードの一部であることは事実です。

ファイルを移動/名前変更する関数を呼び出す前に、Java アプリケーションにすべてのロックを強制的に解放させるにはどうすればよいですか?

これが不可能な場合、コードのどの部分がファイルをロックしているかを確認する簡単な方法はありますか? 閉じられていないファイル ハンドルを見つけるためにコードベース全体を探し回るのは、そこにあるコードの量を考えると悪夢です。

ありがとう

4

3 に答える 3

4

ストリームを適切に (できればブロック内で) 閉じる以外の解決策try.. finallyは、失敗作であり、現状よりも不安定になるリスクがあります。

大規模なコードベースでこれを修正するのは大変なことです。コードをぐるぐる回したくない場合、FindBugsは閉じられていないストリームを見つけるのに優れています。Eclipse プラグインがあり、見つけたバグを興味のあるものだけにフィルターすることができます。

于 2012-07-20T14:52:02.053 に答える
4

File() オブジェクトはファイルをロックしませんが、FileStream (FileInputStream/FileOutputStream) はファイルをロックします。したがって、すべてのストリームをログに記録する、ストリーム用の HelperClass (たとえば、Singleton) を作成する必要があります。

ただし、コードにリークがある場合は、すべてのファイルを強制的に閉じるよりもバグを修正する方がはるかに優れていることに注意してください。

于 2012-07-23T08:09:44.713 に答える
4

デバッガーを使用すると、メモリ内にあるオブジェクトのすべてのインスタンスを表示できます (Netbeans では、Windows | Debugging | Loaded Classes を選択し、右クリック -> インスタンスの表示)。次に、持っているすべてのFileInputStream/FileOutputStreamインスタンスを確認し、移動しようとしているファイルを指しているインスタンスを特定できます。ファイルへの参照が見つかったら、誰がまだ参照を保持しているかを確認できます。

ファイルへの参照を保持している人がいない場合、インスタンスは を呼び出さずに破棄close()された可能性があり、ファイルは通常、ガベージ コレクションの後にのみ解放されます。これにより、以前のアプローチは役に立たなくなります。デバッガーがこれらのストリームを自動的にガベージ コレクションすると思うからです。ストリーム コンストラクター内に条件付きブレークポイントを配置し、コンストラクター パラメーターがファイルを参照している場合にのみ停止するように指示することもできます。

何も見つからない場合は、最後の手段として、System.gc()移動操作の前にいくつかの呼び出しを行い、改善があるかどうかを確認できます。明らかに、これは、実際の問題を見つけるまでの時間を与えるための、簡単な修正にすぎません。

于 2012-07-20T14:09:50.270 に答える