Java NIO - FileLock

Como sabemos, o Java NIO oferece suporte a simultaneidade e multiencadeamento, o que permite que ele lide com vários encadeamentos operando em vários arquivos ao mesmo tempo. Mas, em alguns casos, exigimos que nosso arquivo não seja compartilhado por nenhum encadeamento e fique inacessível.

Para tal requisito, a NIO fornece novamente uma API conhecida como FileLock, que é usada para fornecer bloqueio sobre todo o arquivo ou parte do arquivo, de forma que esse arquivo ou sua parte não seja compartilhado ou acessível.

para fornecer ou aplicar tal bloqueio, temos que usar FileChannel ou AsynchronousFileChannel, que fornece dois métodos lock() e tryLock()para este fim. A fechadura fornecida pode ser de dois tipos -

  • Exclusive Lock - Um bloqueio exclusivo impede que outros programas obtenham um bloqueio sobreposto de qualquer tipo.

  • Shared Lock - Um bloqueio compartilhado evita que outros programas em execução simultânea adquiram um bloqueio exclusivo sobreposto, mas permite que eles adquiram bloqueios compartilhados sobrepostos.

Métodos usados ​​para obter arquivo de bloqueio -

  • lock() - Este método de FileChannel ou AsynchronousFileChannel adquire um bloqueio exclusivo sobre um arquivo associado ao canal fornecido. O tipo de retorno desse método é FileLock, que é usado posteriormente para monitorar o bloqueio obtido.

  • lock(long position, long size, boolean shared) - Este método novamente é o método sobrecarregado do método de bloqueio e é usado para bloquear uma parte específica de um arquivo.

  • tryLock() - Este método retorna um FileLock ou um null se o bloqueio não pôde ser adquirido e ele tenta adquirir um bloqueio explicitamente exclusivo no arquivo deste canal.

  • tryLock(long position, long size, boolean shared) - Este método tenta adquirir um bloqueio em uma determinada região do arquivo deste canal, que pode ser exclusivo ou do tipo compartilhado.

Métodos da classe FileLock

  • acquiredBy() - Este método retorna o canal em cujo arquivo o bloqueio foi adquirido.

  • position() - Este método retorna a posição dentro do arquivo do primeiro byte da região bloqueada. Uma região bloqueada não precisa estar contida, ou mesmo sobrepor, o arquivo subjacente real, portanto, o valor retornado por este método pode exceder o tamanho atual do arquivo.

  • size() - Este método retorna o tamanho da região bloqueada em bytes. Uma região bloqueada não precisa estar contida, ou mesmo sobrepor, o arquivo subjacente real, portanto, o valor retornado por este método pode exceder o tamanho atual do arquivo.

  • isShared() - Este método é usado para determinar se o bloqueio é compartilhado ou não.

  • overlaps(long position,long size) - Este método informa se este bloqueio se sobrepõe ou não ao intervalo de bloqueio fornecido.

  • isValid() - Este método informa se o bloqueio obtido é válido ou não. Um objeto de bloqueio permanece válido até que seja liberado ou o canal de arquivo associado seja fechado, o que ocorrer primeiro.

  • release()- Libera o bloqueio obtido. Se o objeto de bloqueio for válido, a invocação desse método libera o bloqueio e torna o objeto inválido. Se este objeto de bloqueio for inválido, chamar esse método não terá efeito.

  • close()- Este método invoca o método release (). Ele foi adicionado à classe para que pudesse ser usado em conjunto com a construção de bloco de gerenciamento automático de recursos.

Exemplo para demonstrar o bloqueio de arquivo.

O exemplo a seguir cria um bloqueio sobre um arquivo e grava conteúdo nele

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();  
   }  
}

Resultado

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.