質問
それで、私はそれを読むためにファイルをロックしようとしますが、私はIOExceptionを得ました、なぜ考えはありますか?
public static void main(String[] args){
File file = new File("C:\\dev\\harry\\data.txt");
FileReader fileReader = null;
BufferedReader bufferedReader = null;
FileChannel channel = null;
FileLock lock = null;
try{
channel = new RandomAccessFile(file, "rw").getChannel();
lock = channel.lock();
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
String data;
while((data = bufferedReader.readLine()) != null){
System.out.println(data);
}
}catch(IOException e){
e.printStackTrace();
}finally{
try {
lock.release();
channel.close();
if(bufferedReader != null) bufferedReader.close();
if(fileReader != null) fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
そして、このエラーが発生しました IOException: The process cannot access the file because another process has locked a portion of the file
解決
これをコメントの代わりに答えとして追加することもできます。
使用する場合 FileLock
API対応するNIOファイルAPIを使用する必要があります。
他のヒント
私の答えを再現します ここ(削除された場合), 、およびジェフフォスターのフィードバックを追加します:
のインスタンスを考慮して OverlappingFileLockException
例外がスローされ、同じプロセスの別のスレッドが同じファイルをロックしようとしているようです。これは、AとBの間の競合ではなく、B内の競合ではなく、LOCK()メソッドのAPIドキュメントを使用する場合、およびそれが重複するfileLockexceptionをスローする条件を使用する場合、むしろB内の競合です。
要求された領域がこのJava仮想マシンによってすでに保持されている場合、またはこの方法で別のスレッドがすでにブロックされており、同じファイルの重複領域をロックしようとしている場合、要求された領域がすでに保持されています
これを防ぐための唯一の解決策は、Bの他のスレッドを同じファイルでロックまたはファイル内の同じ重複領域を取得できないようにすることです。
IOException
投げられることにはもう少し面白いメッセージがあります。おそらく上記の理論を確認しますが、ソースコード全体を見ることなく、何も確認できません。 lock
メソッドは、排他的ロックが取得されるまでブロックすると予想されます。それが取得された場合、ファイルから読むことに問題はないはずです。 1つの条件を除きます。ファイルオブジェクト(または言い換えれば、2番目/異なるファイル記述子)を使用して、別のスレッドで同じJVMによってファイルが既に開かれている(およびロックされている)場合、最初のファイル記述子で読み取られた読み取りが失敗しますロックが取得された場合(結局、ロックは他のスレッドをロックアウトしません)。
改良されたデザインは、各プロセスに1つのスレッドを持つことで、ファイルに排他的ロックを取得します(単一のファイルオブジェクト、または単一のファイル記述子を使用しながら)一定の時間だけ、必要なアクティビティを実行することです。ファイルしてから、ロックを解放します。
ジェフが指摘したように、NIO APIを使用すると、おそらく問題が解決されるでしょう。これは完全にのためです Filreader APIが新しいファイル記述子を開く可能性, 、ロックが取得されているものとは異なります。
多分あなたが望むのはもっと似ているものです:
FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));