Java NIO - FileLock(文件锁 )

  • 简述

    众所周知,Java NIO支持并发和多线程,这使其能够同时处理对多个文件进行操作的多个线程。但在某些情况下,我们要求我们的文件不会被任何线程共享并且无法访问。
    对于这样的要求,NIO再次提供了一个称为FileLock的API,用于对整个文件或文件的一部分提供锁定,以便该文件或其部分不会被共享或访问。
    为了提供或应用这样的锁,我们必须使用文件通道或异步文件通道,它为此目的提供了两种方法 lock()tryLock()。提供的锁可以有两种类型 :
    • 独占锁 − 独占锁可防止其他程序获取任一类型的重叠锁。
    • 共享锁 − 共享锁可防止其他并发运行的程序获取重叠的独占锁,但允许它们获取重叠的共享锁。
    用于获取锁定文件的方法 −
    • lock() − 这种文件通道或异步文件通道的方法获取与给定通道关联的文件的独占锁。此方法的返回类型是文件锁定,它进一步用于监视获得的锁定。
    • lock(long position, long size, boolean shared) − 此方法再次是锁定方法的重载方法,用于锁定文件的特定部分。
    • tryLock() − 如果无法获取锁,并且尝试获取此通道文件的显式独占锁,则此方法返回 FileLock 或空值。
    • tryLock(long position, long size, boolean shared) − 此方法尝试获取此通道文件的给定区域的锁,该区域可以是独占的或共享类型的。
  • 文件锁定类的方法

    • acquireedBy() − 此方法返回获取其文件锁定的通道。
    • position() − 此方法返回锁定区域的第一个字节的文件内的位置。锁定区域不需要包含在实际的基础文件中,甚至不需要与实际的基础文件重叠,因此此方法返回的值可能会超过文件的当前大小。
    • size() − 此方法返回锁定区域的大小(以字节为单位)。锁定区域不需要包含在实际的基础文件中,甚至不需要与实际的基础文件重叠,因此此方法返回的值可能会超过文件的当前大小。
    • isShared() − 此方法用于确定锁定是否共享。
    • overlaps(long position,long size) − 此方法指示此锁是否与给定的锁定范围重叠。
    • isValid() − 此方法指示获取的锁是否有效。锁定对象在释放或关联的文件通道关闭之前一直有效,以先到者为准。
    • release() − 释放获得的锁。如果锁定对象有效,则调用此方法将释放锁定并使该对象无效。如果此锁定对象无效,则调用此方法将不起作用。
    • close() − 此方法调用释放() 方法。它被添加到类中,以便它可以与自动资源管理块构造结合使用。
  • 演示文件锁定的示例。

    以下示例创建对文件的锁定并向其写入内容
    
    package com.java.nio;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.FileLock;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    public class FileLockExample {
       public static void main(String[] args) throws IOException {
          String input = "Demo text to be written in locked mode.";  
          System.out.println("Input string to the test file is: " + input);  
          ByteBuffer buf = ByteBuffer.wrap(input.getBytes());  
          String fp = "D:file.txt";  
          Path pt = Paths.get(fp);  
          FileChannel channel = FileChannel.open(pt, StandardOpenOption.WRITE,StandardOpenOption.APPEND);  
          channel.position(channel.size() - 1); // position of a cursor at the end of file       
          FileLock lock = channel.lock();   
          System.out.println("The Lock is shared: " + lock.isShared());  
          channel.write(buf);  
          channel.close(); // Releases the Lock  
          System.out.println("Content Writing is complete. Therefore close the channel and release the lock.");  
          PrintFileCreated.print(fp);  
       }  
    }
    
    
    package com.java.nio;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    public class PrintFileCreated {
       public static void print(String path) throws IOException {  
          FileReader filereader = new FileReader(path);  
          BufferedReader bufferedreader = new BufferedReader(filereader);  
          String tr = bufferedreader.readLine();    
          System.out.println("The Content of testout.txt file is: ");  
          while (tr != null) {      
             System.out.println("    " + tr);  
             tr = bufferedreader.readLine();  
          }  
       filereader.close();  
       bufferedreader.close();  
       }  
    }
    
  • 输出

    
    Input string to the test file is: Demo text to be written in locked mode.
    The Lock is shared: false
    Content Writing is complete. Therefore close the channel and release the lock.
    The Content of testout.txt file is: 
    To be or not to be?Demo text to be written in locked mode.