所以我试图锁定文件来读取它,但我得到了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。
从这里复制我的答案(以防被删除),并添加Jeff Foster的反馈:
考虑到抛出了OverlappingFileLockException
异常的实例,看来同一进程中的另一个线程正试图锁定同一文件。这不是a和B之间的冲突,而是B内部的冲突,如果通过关于lock()方法的API文档,并且当抛出OverlappingFileLockException:的条件时
如果与请求的锁重叠该Java已经拥有该区域虚拟机,或者如果其他线程已在此方法中被阻止,并且正在尝试锁定重叠同一文件的区域
防止这种情况的唯一解决方案是阻止B中的任何其他线程获取同一文件或文件中相同重叠区域的锁。
抛出的IOException
有一个更有趣的消息。它可能证实了上述理论,但如果不查看整个源代码,我就无法证实任何事情。lock
方法预计将被阻塞,直到获得排他锁为止。如果它是被获取的,那么从文件中读取应该没有问题。除了一个条件。如果文件已经被不同线程中的同一JVM使用file对象(或者换句话说,第二个/不同的文件描述符)打开(并锁定),那么即使获取了锁,对第一个文件描述符的尝试读取也将失败(毕竟,锁不会锁定其他线程)。
一种改进的设计是,在每个进程中都有一个线程,该线程只在一定时间内获取文件的独占锁(同时使用单个file对象或单个文件描述符),在文件中执行所需的活动,然后释放锁。
正如Jeff所指出的,使用NIOAPI可能会解决问题。这完全是由于FileReader API打开一个新文件描述符的可能性,该描述符与获取锁的描述符不同。
也许你想要的是更像的东西
FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));