Comment puis-je verrouiller un fichier en utilisant java (si possible)

J’ai un processus Java qui ouvre un fichier en utilisant un FileReader. Comment puis-je empêcher un autre processus (Java) d’ouvrir ce fichier, ou au moins signaler au second processus que le fichier est déjà ouvert? Est-ce que le deuxième processus obtient automatiquement une exception si le fichier est ouvert (ce qui résout mon problème) ou dois-je l’ouvrir explicitement dans le premier processus avec une sorte de drapeau ou d’argument?

Clarifier:

J’ai une application Java qui répertorie un dossier et ouvre chaque fichier dans la liste pour le traiter. Il traite chaque fichier après l’autre. Le traitement de chaque fichier consiste à le lire et à effectuer des calculs en fonction du contenu, ce qui prend environ 2 minutes. J’ai aussi une autre application Java qui fait la même chose, mais qui écrit sur le fichier. Ce que je veux, c’est pouvoir exécuter ces applications en même temps pour que le scénario se déroule comme suit. ReadApp répertorie le dossier et trouve les fichiers A, B, C. Il ouvre le fichier A et commence la lecture. WriteApp répertorie le dossier et trouve les fichiers A, B, C. Il ouvre le fichier A, voit qu’il est ouvert (à une exception ou ailleurs) et va au fichier B. ReadApp termine le fichier A et continue à B. est ouvert et continue à C. Il est crucial que WriteApp n’écrit pas pendant que ReadApp lit le même fichier ou vice versa. Ce sont des processus différents.

FileChannel.lock est probablement ce que vous voulez.

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

(Disclaimer: Code non compilé et certainement pas testé.)

Notez la section intitulée “dépendances de la plate-forme” dans la documentation de l’ API pour FileLock .

N’utilisez pas les classes du package java.io , utilisez plutôt le package java.nio . Ce dernier a une classe FileLock . Vous pouvez appliquer un verrou à un 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 resortingeve 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) { } 

Si vous pouvez utiliser Java NIO ( JDK 1.4 ou version ultérieure ), je pense que vous recherchez java.nio.channels.FileChannel.lock()

FileChannel.lock ()

utilisez java.nio.channels.FileLock conjointement avec java.nio.channels.FileChannel

Ce n’est peut-être pas ce que vous recherchez, mais dans l’intérêt d’un problème sous un autre angle ….

Ces deux processus Java peuvent-ils vouloir accéder au même fichier dans la même application? Peut-être que vous pouvez simplement filtrer tous les access au fichier via une seule méthode synchronisée (ou, mieux encore, avec JSR-166 )? De cette façon, vous pouvez contrôler l’access au fichier et peut-être même les demandes d’access aux files d’attente.

Utilisez un RandomAccessFile, obtenez son canal, puis appelez lock (). Le canal fourni par les stream d’entrée ou de sortie ne dispose pas de privilèges suffisants pour se verrouiller correctement. Veillez à appeler unlock () dans le bloc finally (la fermeture du fichier ne libère pas nécessairement le verrou).

Il y a quelques années, j’ai trouvé le même problème lorsque j’ai écrit une application qui exigeait que plusieurs utilisateurs MacOS / Windows partagent les mêmes données dans plusieurs fichiers. Le locking des fichiers ne fonctionnait pas sur MacOS, alors j’ai créé ma propre classe ‘ioFile’ qui conservait son propre registre d’access aux fichiers – ouvrir r / o, ouvrir r / w, etc., et qui “possédait” le verrou. C’est le seul moyen au moment où je pourrais contrôler l’access de différents utilisateurs sur différentes machines utilisant différents systèmes d’exploitation.

Vous trouverez ci-dessous un exemple de code d’extrait de code pour verrouiller un fichier jusqu’à ce qu’il soit traité par JVM.

  public static void main(Ssortingng[] 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(); } } } 

Si vous placez votre access aux fichiers en mode synchronisé, une seule instance de thread peut y entrer, d’autres attendent jusqu’à ce que le travail soit terminé.

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

Vous utilisez java.nio. * API pour verrouiller un fichier. Cependant, cela ne garantit pas le locking. Cela dépend si le système d’exploitation sous-jacent prend en charge le locking ou non. Si je comprends bien, les systèmes d’exploitation comme Linux ne prennent pas en charge le locking et vous ne pouvez donc pas verrouiller même si vous utilisez ces API