0

Related to this question Java writing to a deleted file only in my case i'm doing the reading. And per that comment, yes, Windows block deletes and Unix doesn't. and under unix never throws any IOException

the code is a poor-man's tail -f, where i have a java thread watching each log file in a directory. my current issue is if the file is deleted, i'm not handling it. I need to abort and start a new thread or something. I didn't even realize it was an issue, as the below code throws no exceptions under Unix

the code

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
String line = null;

while (true) {
    try {
        line = br.readLine();
        // will return null if no lines added
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (line == null) {
        // sleep if no new lines added to file
        Thread.sleep(1000);

    } else {
        // line is not null, process line
    }
}

Tomorrow I'll try adding this check before the sleep, maybe is sufficient

if (!f.exists()) {
    // file gone, aborting this thread
    return;
}

Anyone have other ideas?

Community
  • 1
  • 1
Steve Renyolds
  • 1,341
  • 2
  • 9
  • 10

2 Answers2

2

When you reach the end of a file, BufferedReader should always return a null whether it has been deleted or not. Its not something you should have to check for.

Can you show us some code because its very hard to stop the BufferedReader not returning a null?

This program

public class Main {

    public static void main(String... args) throws IOException {
        PrintWriter pw = new PrintWriter("file.txt");
        for (int i = 0; i < 1000; i++)
            pw.println("Hello World");
        pw.close();

        BufferedReader br = new BufferedReader(new FileReader("file.txt"));
        br.readLine();
        if (!new File("file.txt").delete())
            throw new AssertionError("Could not delete file.");
        while (br.readLine() != null) ;
        br.close();
        System.out.println("The end of file was reached.");
    }
}

On windows prints

AssertionError: Could not delete file.

On Linux prints

The end of file was reached.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Once you have read the end of the file, you cannot go back and try again. The only way to keep the file handle open is to not read the end of the file. You can do this by checking the file length before performing the read (which means you can't use readLine directly) – Peter Lawrey Jul 06 '12 at 05:27
1

You could watch your directory using WatchService API for changes and act accordingly

GETah
  • 20,922
  • 7
  • 61
  • 103