Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: opening and reading from a file without locking it

I need to be able to mimic 'tail -f' with Java. I'm trying to read a log file as it's being written by another process, but when I open the file to read it, it locks the file and the other process can't write to it anymore. Any help would be greatly appreciated!

Here is the code that I'm using currently:

public void read(){
    Scanner fp = null;
    try{
        fp = new Scanner(new FileReader(this.filename));
        fp.useDelimiter("\n");
    }catch(java.io.FileNotFoundException e){
        System.out.println("java.io.FileNotFoundException e");
    }
    while(true){
        if(fp.hasNext()){
            this.parse(fp.next());
        }           
    }       
}
like image 694
rogue780 Avatar asked Mar 29 '10 10:03

rogue780


People also ask

How do you unlock a file in Java?

Verify that the file has not been corrupted and that the file extension matches the format of the file. A reason why would you want to unlock the file is one good way to start the question. The operating system won't permit it. There is nothing you can do about it in Java.

What is file locking in Java?

A token representing a lock on a region of a file. A file-lock object is created each time a lock is acquired on a file via one of the lock or tryLock methods of the FileChannel class, or the lock or tryLock methods of the AsynchronousFileChannel class. A file-lock object is initially valid.

What are some of the methods that Java provides to lock files?

In Java, a file lock can be obtained using FileChannel , which provides two methods — lock() and tryLock() — for this purpose. The lock() method acquires an exclusive lock on entire file, whereas the lock(long position, long size, boolean shared) method can be used to acquire a lock on the given region of a ile.


1 Answers

Rebuilding tail is tricky due to some special cases like file truncation and (intermediate) deletion. To open the file without locking use StandardOpenOption.READ with the new Java file API like so:

try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) {
    InputStreamReader reader = new InputStreamReader(is, fileEncoding);
    BufferedReader lineReader = new BufferedReader(reader);
    // Process all lines.
    String line;
    while ((line = lineReader.readLine()) != null) {
        // Line content content is in variable line.
    }
}

For my attempt to create a tail in Java see:

  • Method examineFile(…) in https://github.com/AugustusKling/yield/blob/master/src/main/java/yield/input/file/FileMonitor.java
  • The above is used by https://github.com/AugustusKling/yield/blob/master/src/main/java/yield/input/file/FileInput.java to create a tail operation. The queue.feed(lineContent) passes line content for processing by listeners and would equal your this.parse(…).

Feel free to take inspiration from that code or simply copy the parts you require. Let me know if you find any issues that I'm not aware of.

like image 173
Augustus Kling Avatar answered Oct 20 '22 06:10

Augustus Kling