如何使用java锁定文件(如果可能)
我有一个Java进程,它使用FileReader打开一个文件。如何防止另一个(Java)进程打开此文件,或者至少通知第二个进程该文件已打开?如果文件已打开(这解决了我的问题),这会自动使第二个进程出现异常吗?还是必须在第一个进程中使用某种标志或参数显式打开它 澄清:如何使用java锁定文件(如果可能),java,file-io,Java,File Io,我有一个Java进程,它使用FileReader打开一个文件。如何防止另一个(Java)进程打开此文件,或者至少通知第二个进程该文件已打开?如果文件已打开(这解决了我的问题),这会自动使第二个进程出现异常吗?还是必须在第一个进程中使用某种标志或参数显式打开它 澄清: 我有一个Java应用程序,它列出一个文件夹,并打开列表中的每个文件进行处理。它一个接一个地处理每个文件。每个文件的处理包括读取文件和根据内容进行计算,大约需要2分钟。我还有另一个Java应用程序,它也做同样的事情,但却在文件上写。我
我有一个Java应用程序,它列出一个文件夹,并打开列表中的每个文件进行处理。它一个接一个地处理每个文件。每个文件的处理包括读取文件和根据内容进行计算,大约需要2分钟。我还有另一个Java应用程序,它也做同样的事情,但却在文件上写。我想要的是能够同时运行这些应用程序,所以场景是这样的。ReadApp列出文件夹并查找文件A、B、C。它打开文件A并开始读取。WriteApp列出文件夹并查找文件A、B、C。它打开文件A,看到文件A处于打开状态(通过异常或其他方式),然后转到文件B。ReadApp完成文件A并继续到B。它看到文件A处于打开状态并继续到C。在ReadApp读取同一文件时,WriteApp不写入非常重要,反之亦然。它们是不同的进程。如果您可以使用Java NIO(JDK 1.4或更高版本),那么我认为您正在寻找
Java.NIO.channels.FileChannel.lock()
如果您可以使用JavaNIO(JDK1.4或更高版本),那么我认为您正在寻找
Java.NIO.channels.FileChannel.lock()
与一起使用与文件通道一起使用。锁定可能是您想要的
try (
FileInputStream in = new FileInputStream(file);
java.nio.channels.FileLock lock = in.getChannel().lock();
Reader reader = new InputStreamReader(in, charset)
) {
...
}
(免责声明:代码未编译,当然也未测试。)
请注意。FileChannel.lock中标题为“平台依赖项”的部分可能就是您想要的
try (
FileInputStream in = new FileInputStream(file);
java.nio.channels.FileLock lock = in.getChannel().lock();
Reader reader = new InputStreamReader(in, charset)
) {
...
}
(免责声明:代码未编译,当然也未测试。)
请注意。中标题为“平台依赖项”的部分使用RandomAccessFile,获取其频道,然后调用lock()。输入或输出流提供的通道没有足够的权限正确锁定。确保在finally块中调用unlock()(关闭文件不一定会解除锁定)。使用RandomAccessFile,获取其通道,然后调用lock()。输入或输出流提供的通道没有足够的权限正确锁定。请确保在finally块中调用unlock()(关闭文件不一定会解除锁定)。这可能不是您要寻找的,而是为了从另一个角度解决问题
这两个Java进程是否希望在同一个应用程序中访问同一个文件?也许您可以通过一个同步的方法(或者更好的是,使用)过滤对文件的所有访问?这样,您就可以控制对文件的访问,甚至可以对访问请求进行排队。这可能不是您想要的,而是为了从另一个角度解决问题
这两个Java进程是否希望在同一个应用程序中访问同一个文件?也许您可以通过一个同步的方法(或者更好的是,使用)过滤对文件的所有访问?这样,您就可以控制对文件的访问,甚至可以对访问请求进行排队。不要使用
java.io
包中的类,而是使用java.nio
包。后者有一个FileLock
类。您可以对文件通道
应用锁
try {
// Get a file channel for the file
File file = new File("filename");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Use the file channel to create a lock on the file.
// This method blocks until it can retrieve the lock.
FileLock lock = channel.lock();
/*
use channel.lock OR channel.tryLock();
*/
// Try acquiring the lock without blocking. This method returns
// null or throws an exception if the file is already locked.
try {
lock = channel.tryLock();
} catch (OverlappingFileLockException e) {
// File is already locked in this thread or virtual machine
}
// Release the lock - if it is not null!
if( lock != null ) {
lock.release();
}
// Close the file
channel.close();
} catch (Exception e) {
}
不要使用
java.io
包中的类,而是使用java.nio
包。后者有一个FileLock
类。您可以对文件通道
应用锁
try {
// Get a file channel for the file
File file = new File("filename");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Use the file channel to create a lock on the file.
// This method blocks until it can retrieve the lock.
FileLock lock = channel.lock();
/*
use channel.lock OR channel.tryLock();
*/
// Try acquiring the lock without blocking. This method returns
// null or throws an exception if the file is already locked.
try {
lock = channel.tryLock();
} catch (OverlappingFileLockException e) {
// File is already locked in this thread or virtual machine
}
// Release the lock - if it is not null!
if( lock != null ) {
lock.release();
}
// Close the file
channel.close();
} catch (Exception e) {
}
下面是一个示例代码片段,用于锁定文件,直到JVM完成其处理
public static void main(String[] args) throws InterruptedException {
File file = new File(FILE_FULL_PATH_NAME);
RandomAccessFile in = null;
try {
in = new RandomAccessFile(file, "rw");
FileLock lock = in.getChannel().lock();
try {
while (in.read() != -1) {
System.out.println(in.readLine());
}
} finally {
lock.release();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
下面是一个示例代码片段,用于锁定文件,直到JVM完成其处理
public static void main(String[] args) throws InterruptedException {
File file = new File(FILE_FULL_PATH_NAME);
RandomAccessFile in = null;
try {
in = new RandomAccessFile(file, "rw");
FileLock lock = in.getChannel().lock();
try {
while (in.read() != -1) {
System.out.println(in.readLine());
}
} finally {
lock.release();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果要使用winscp或ftp进行传输,请在unix中使用此选项:
public static void isFileReady(File entry) throws Exception {
long realFileSize = entry.length();
long currentFileSize = 0;
do {
try (FileInputStream fis = new FileInputStream(entry);) {
currentFileSize = 0;
while (fis.available() > 0) {
byte[] b = new byte[1024];
int nResult = fis.read(b);
currentFileSize += nResult;
if (nResult == -1)
break;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("currentFileSize=" + currentFileSize + ", realFileSize=" + realFileSize);
} while (currentFileSize != realFileSize);
}
如果要使用winscp或ftp进行传输,请在unix中使用此选项:
public static void isFileReady(File entry) throws Exception {
long realFileSize = entry.length();
long currentFileSize = 0;
do {
try (FileInputStream fis = new FileInputStream(entry);) {
currentFileSize = 0;
while (fis.available() > 0) {
byte[] b = new byte[1024];
int nResult = fis.read(b);
currentFileSize += nResult;
if (nResult == -1)
break;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("currentFileSize=" + currentFileSize + ", realFileSize=" + realFileSize);
} while (currentFileSize != realFileSize);
}
您是指进程(两个JVM)还是线程(相同JVM)中的“进程”。对答案的影响是至关重要的。检查这里显示解决方案的示例代码:您指的是进程(两个JVM)中的“进程”还是线程(同一个JVM)。对答案的影响是至关重要的。请检查显示解决方案的示例代码:可能。取决于OP对“过程”的定义。“文件锁代表整个Java虚拟机。它们不适合控制同一虚拟机内多个线程对文件的访问。”@Stu:我知道你很久以前就回答过这个问题,但我希望您能详细说明您所说的
文件锁代表整个Java虚拟机持有的意思。它们不适用于控制同一虚拟机内多个线程对文件的访问
@Harry他从文档中引用:这意味着它对线程不可见,但会影响其他进程。@Harry:为了给这些necro注释添加更多内容,假设您使用Java为Tomcat网站提供服务。您可能有很多线程,每个线程都为来自web浏览器的一个请求提供服务。但是,它们都控制着相同的文件锁定机制,就像厨房里有太多厨师一样。一个请求可能在第二个请求的中间完成,并且当你还在某个中间时,你的文件突然“解锁”,然后像CrOnWork之类的其他进程可能锁定它,然后你意外地丢失了你的锁,并且你的请求无法完成……也许。取决于OP对“过程”的定义。“文件锁代表整个Java虚拟机。它们不适合控制同一虚拟机内多个线程对文件的访问。”@Stu:我知道你很久以前就回答过这个问题,但是