Frage

Ich habe einen Java -Prozess, der eine Datei mit einem Filerader öffnet. Wie kann ich verhindern, dass ein anderer Java -Prozess diese Datei öffnet, oder zumindest den zweiten Prozess, dass die Datei bereits geöffnet ist? Wird der zweite Vorgang automatisch eine Ausnahme erhält, wenn die Datei geöffnet ist (was mein Problem löst) oder muss ich sie im ersten Prozess mit einer Art Flag oder Argument explizit öffnen?

Um klarzustellen:

Ich habe eine Java -App, die einen Ordner auflistet und jede Datei in der Auflistung öffnet, um ihn zu verarbeiten. Es verarbeitet jede Datei nach der anderen. Die Verarbeitung jeder Datei besteht darin, sie zu lesen und einige Berechnungen auf der Grundlage des Inhalts durchzuführen, und es dauert ungefähr 2 Minuten. Ich habe auch eine andere Java -App, die dasselbe tut, aber stattdessen in der Datei schreibt. Ich möchte diese Apps gleichzeitig ausführen können, damit das Szenario so geht. ReadApp listet den Ordner auf und findet die Dateien A, B, C. Es öffnet die Datei A und startet das Lesen. WriteApp listet den Ordner auf und findet die Dateien A, B, C. Es öffnet die Datei A, sieht, dass es offen ist (nach einer Ausnahme oder nach wie vor) und geht zu Datei B. ReadApp beendet die Datei A und fährt fort. ist offen und setzt sich fort. Sie sind unterschiedliche Prozesse.

War es hilfreich?

Lösung

Filechannel.lock ist wahrscheinlich das, was Sie wollen.

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

(Haftungsausschluss: Code nicht kompiliert und sicherlich nicht getestet.)

Beachten Sie den Abschnitt mit dem Titel "Plattformabhängigkeiten" in der API -DOC für Filelock.

Andere Tipps

Verwenden Sie die Klassen nicht in derjava.io Paket, stattdessen die verwenden java.nio Paket . Letzteres hat eine FileLock Klasse. Sie können ein Schloss auf a anwenden 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) {
    }

Wenn Sie verwenden können Java Nio (JDK 1,4 oder mehr), dann denke ich, dass du danach suchst java.nio.channels.FileChannel.lock()

Filechannel.lock ()

Dies ist vielleicht nicht das, wonach Sie suchen, sondern um ein Problem aus einem anderen Blickwinkel zu bekommen ....

Sind diese beiden Java -Prozesse, die in derselben Anwendung möglicherweise auf dieselbe Datei zugreifen möchten? Vielleicht können Sie einfach den gesamten Zugriff auf die Datei über eine einzelne, synchronisierte Methode filtern (oder sogar noch besser, verwenden JSR-166)? Auf diese Weise können Sie den Zugriff auf die Datei steuern und möglicherweise sogar Zugriffsanforderungen für Warteschlangen.

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).

I found the same issue some years back when I wrote an application that required multiple users on MacOS/Windows to share the same data in multiple files. File locking didn't work on MacOS so I created my own 'ioFile' class which maintained it's own register of file access - open r/o, open r/w, etc, and who 'owned' the lock. This is the only way at the time I could control access from different users on different machines using different OS's.

Below is a sample snippet code to lock a file until it's process is done by 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();
        }
    }

}

If you put your file access in synchronized block, only one instance of thread can enter into it, others will wait, until one has finished it's work.

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

     }  

You an use java.nio.* APIs for locking a file. However that doesn't guarantee locking, It depends on if the underlying OS supports locking or not. As I understand Operating systems like Linux doens't support locking and hence you cannot lock even if you use these APIs

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top