如何使用 java 锁定文件(如果可能)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/128038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I lock a file using java (if possible)
提问by Paralife
I have a Java process that opens a file using a FileReader. How can I prevent another (Java) process from opening this file, or at least notify that second process that the file is already opened? Does this automatically make the second process get an exception if the file is open (which solves my problem) or do I have to explicitly open it in the first process with some sort of flag or argument?
我有一个使用 FileReader 打开文件的 Java 进程。如何防止另一个(Java)进程打开这个文件,或者至少通知第二个进程该文件已经打开?如果文件已打开(这解决了我的问题),这是否会自动使第二个进程出现异常,或者我是否必须在第一个进程中使用某种标志或参数显式打开它?
To clarify:
澄清:
I have a Java app that lists a folder and opens each file in the listing for processing it. It processes each file after the other. The processing of each file consists of reading it and doing some calculations based on the contents and it takes about 2 minutes. I also have another Java app that does the same thing but instead writes on the file. What I want is to be able to run these apps at the same time so the scenario goes like this. ReadApp lists the folder and finds files A, B, C. It opens file A and starts the reading. WriteApp lists the folder and finds files A, B, C. It opens file A, sees that is is open (by an exception or whatever way) and goes to file B. ReadApp finishes file A and continues to B. It sees that it is open and continues to C. It is crucial that WriteApp doesn't write while ReadApp is reading the same file or vice versa. They are different processes.
我有一个 Java 应用程序,它列出了一个文件夹并打开列表中的每个文件进行处理。它一个接一个地处理每个文件。每个文件的处理包括读取它并根据内容进行一些计算,大约需要 2 分钟。我还有另一个 Java 应用程序,它执行相同的操作,而是写入文件。我想要的是能够同时运行这些应用程序,所以场景是这样的。ReadApp 列出文件夹并找到文件 A、B、C。它打开文件 A 并开始读取。WriteApp 列出文件夹并找到文件 A、B、C。它打开文件 A,看到它是打开的(通过异常或任何方式)并转到文件 B。ReadApp 完成文件 A 并继续到 B。它看到它是开放的并继续到 C。WriteApp 不重要' 在 ReadApp 读取同一个文件时写入,反之亦然。它们是不同的过程。
采纳答案by Tom Hawtin - tackline
FileChannel.lock is probably what you want.
FileChannel.lock 可能就是你想要的。
try (
FileInputStream in = new FileInputStream(file);
java.nio.channels.FileLock lock = in.getChannel().lock();
Reader reader = new InputStreamReader(in, charset)
) {
...
}
(Disclaimer: Code not compiled and certainly not tested.)
(免责声明:代码未编译,当然也未测试。)
Note the section entitled "platform dependencies" in the API doc for FileLock.
回答by KC Baltz
If you can use Java NIO(JDK 1.4 or greater), then I think you're looking for java.nio.channels.FileChannel.lock()
如果您可以使用Java NIO(JDK 1.4 或更高版本),那么我认为您正在寻找java.nio.channels.FileChannel.lock()
回答by Matt
use java.nio.channels.FileLockin conjunction with java.nio.channels.FileChannel
将java.nio.channels.FileLock与java.nio.channels.FileChannel结合使用
回答by Kevin Day
Use a RandomAccessFile, get it's channel, then call lock(). The channel provided by input or output streams does not have sufficient privileges to lock properly. Be sure to call unlock() in the finally block (closing the file doesn't necessarily release the lock).
使用 RandomAccessFile,获取它的频道,然后调用 lock()。输入或输出流提供的通道没有足够的权限来正确锁定。确保在 finally 块中调用 unlock() (关闭文件不一定释放锁)。
回答by pkaeding
This may not be what you are looking for, but in the interest of coming at a problem from another angle....
这可能不是您想要的,而是为了从另一个角度解决问题......
Are these two Java processes that might want to access the same file in the same application? Perhaps you can just filter all access to the file through a single, synchronized method (or, even better, using JSR-166)? That way, you can control access to the file, and perhaps even queue access requests.
这两个 Java 进程是否可能想要访问同一个应用程序中的同一个文件?也许您可以通过一个单一的、同步的方法(或者更好地,使用JSR-166)过滤对文件的所有访问?这样,您就可以控制对文件的访问,甚至可以对访问请求进行排队。
回答by ayengin
Don't use the classes in thejava.io
package, instead use the java.nio
package . The latter has a FileLock
class. You can apply a lock to a FileChannel
.
不要使用java.io
包中的类,而是使用java.nio
包。后者有一个FileLock
类。您可以对FileChannel
.
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) {
}
回答by Ajay Kumar
Below is a sample snippet code to lock a file until it's process is done by JVM.
下面是一个示例代码片段,用于锁定文件,直到 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();
}
}
}