我怎样才能locking一个文件使用Java(如果可能)

我有一个使用FileReader打开文件的Java进程。 如何防止另一个(Java)进程打开这个文件,或者至less通知第二个进程该文件已经打开? 这是否会自动使第二个进程得到一个exception,如果文件是打开的(这解决了我的问题)还是必须明确地打开它在第一个进程中的某种标志或参数?

澄清:

我有一个Java应用程序列出了一个文件夹,并打开列表中的每个文件来处理它。 它处理每个文件之后。 每个文件的处理包括读取它并根据内容进行一些计算,大约需要2分钟。 我也有另一个Java应用程序,做相同的事情,而是写在文件上。 我想要的是能够同时运行这些应用程序,所以场景就像这样。 ReadApp列出文件夹并find文件A,B,C,打开文件A并开始读取。 WriteApp列出文件夹,并find文件A,B,C。它打开文件A,看到它是打开的(通过例外或任何方式)并进入文件B. ReadApp完成文件A并继续到B.它看到它是开放的,并继续到C.当ReadApp正在读取同一个文件时,WriteApp不写,反之亦然。 他们是不同的过程。

FileChannel.lock可能是你想要的。

FileInputStream in = new FileInputStream(file); try { java.nio.channels.FileLock lock = in.getChannel().lock(); try { Reader reader = new InputStreamReader(in, charset); ... } finally { lock.release(); } } finally { in.close(); } 

(免责声明:代码没有编译,当然也没有testing。)

请注意FileLock的API文档中标题为“平台依赖性”的部分。

不要使用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) { } 

如果您可以使用Java NIOJDK 1.4或更高版本 ),那么我认为您正在寻找java.nio.channels.FileChannel.lock()

FileChannel.lock()

结合使用java.nio.channels.FileLock和java.nio.channels.FileChannel

这可能不是你正在寻找的,但是为了从另一个angular度来解决问题。

这两个Java进程是否可能想要在同一个应用程序中访问相同的文件? 也许你可以通过一个单一的,同步的方法(或者更好的是,使用JSR-166 )来过滤对文件的所有访问? 这样,您可以控制对文件的访问,甚至可以对访问请求进行排队。

使用RandomAccessFile,获取它的通道,然后调用lock()。 input或输出stream提供的通道没有足够的权限来正确locking。 一定要在finally块中调用unlock()(closures文件不一定会释放锁)。

几年前,当我编写一个需要MacOS / Windows上的多个用户共享多个文件中的相同数据的应用程序时,我发现了同样的问题。 文件locking在MacOS上不起作用,所以我创build了自己的“ioFile”类,它保留了它自己的文件访问寄存器 – 打开r / o,打开r / w等,谁拥有这个锁。 这是当时我能控制不同用户使用不同操作系统的机器访问的唯一方法。

下面是一个示例代码来locking文件,直到它的过程由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(); } } } 

如果你把文件的访问放在同步块中,只有一个线程实例可以进入,其他的将等待,直到完成工作。

 public class FileReader{ public void read() { synchronized (this) { //put you file access here } } } 
 package tips.javabeat.nio.lock; import java.io.*; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; public class FileLockTest { public static void main(String[] args) throws Exception { RandomAccessFile file = null; FileLock fileLock = null; try { file = new RandomAccessFile("FileToBeLocked", "rw"); FileChannel fileChannel = file.getChannel(); fileLock = fileChannel.tryLock(); if (fileLock != null){ System.out.println("File is locked"); accessTheLockedFile(); } }finally{ if (fileLock != null){ fileLock.release(); } } } static void accessTheLockedFile(){ try{ FileInputStream input = new FileInputStream("FileToBeLocked"); int data = input.read(); System.out.println(data); }catch (Exception exception){ exception.printStackTrace(); } } 

您可以使用java.nio。* API来locking文件。 但是,这并不能保证locking,这取决于底层操作系统是否支持locking。 据我了解,像Linux这样的操作系统不支持locking,因此即使使用这些API也不能locking