2

I would like to replace some items in a file, based on some regular expressions. In order to do that:

  • I read the file line per line
  • For every line, I check for the regular expression and I perform the replacement
  • Every line gets written in an array of strings

When all this is finished, I try to delete the file (in order to recreate it again with the replaced lines).

For some reason this does not work: it seems that Java keeps a handle on that file, even after the BufferedReader has been closed.

Does anybody have a solution for this (newbie) question?

Code excerpt:

      Pattern oDatePattern   = Pattern.compile("at \\d{2}:\\d{2}:\\d{2} "); // meaning: "at xx:xx:xx"
      Pattern oTimePattern   = Pattern.compile("Kernel time [0-9]*\\.?[0-9]+ User time: [0-9]*\\.?[0-9]+"); // "[0-9]*\.?[0-9]+" stands for any floating point number
      Pattern oMemoryPattern = Pattern.compile("\\([0-9,A-F]*\\)"); // "[0-9,A-F]*" stands for any hexadecimal number 
      Matcher oDateMatcher;
      Matcher oTimeMatcher;
      Matcher oMemoryMatcher;

      List<String> sLog_Content = new ArrayList<String>();

      BufferedReader br = new BufferedReader(new FileReader(sLp_LogFile));
      try {
        String sLine = br.readLine();

        while (sLine != null) {
          System.out.println("ORIG : " + sLine);
          oDateMatcher = oDatePattern.matcher(sLine);
          sLine        = oDateMatcher.replaceAll("at <timestamp> ");
          oTimeMatcher = oTimePattern.matcher(sLine);
          sLine        = oTimeMatcher.replaceAll("Kernel time <Kernel_Time_usage> User time: <User_Time_usage>");
          oMemoryMatcher = oMemoryPattern.matcher(sLine);
          sLine          = oMemoryMatcher.replaceAll("<Memory_Address>");
          System.out.println("REPL : " + sLine);
          sLog_Content.add(sLine);
          sLine = br.readLine();
        }
      } finally {
        br.close();
      }

      System.out.println("All lines are read and regex replaced, try to delete the file");

      File tst_File = new File(sLp_LogFile);
      if (tst_File.exists()) {
        System.out.println(sLp_LogFile + " exists");
      } else {
        System.out.println(sLp_LogFile + " does not exist");
      }

      if (tst_File.delete()) {
        System.out.println(sLp_LogFile + " is deleted");
      } else {
        System.out.println(sLp_LogFile + " is not deleted");
      }

Output logs:

ORIG : Reading buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000 lines 126000, total lines read 126000)
REPL : Reading buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000 lines 126000, total lines read 126000)
...
ORIG : Sending buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000, lines 126000, total lines sent 126000)
REPL : Sending buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000, lines 126000, total lines sent 126000)
...
ORIG : Kernel time 0.2808 User time: 0.312
REPL : Kernel time <Kernel_Time_usage> User time: <User_Time_usage>
...
All lines are read and regex replaced, try to delete the file
D:\Logfile_lp.log exists
D:\Logfile_lp.log is not deleted
5
  • I have the following suggestion: preserve FileReader reference and close it as well. If you use Java 7 or later, you can use TRY-with-resources syntax. Commented Apr 18, 2016 at 14:37
  • @brso05 - Unnecessary. The close() call on the BufferedReader will call close() on the FileReader. Commented Apr 18, 2016 at 14:39
  • can you try Files.delete(path)? (needs java7+) Commented Apr 18, 2016 at 14:39
  • Just as a test, I have preserved FileReader and closed that one, but that did not solve the issue. Commented Apr 18, 2016 at 14:55
  • I have tried to use "Files", but it seems not to work (Files is not found). Commented Apr 18, 2016 at 15:01

4 Answers 4

3

One possible explanation is that your application has the file open somewhere else.

Or it could be another application that has the file open.

Or maybe the application / user has permission to read the file but not to delete it.


I concur with the suggestion of using Files.delete ..

Sign up to request clarification or add additional context in comments.

1 Comment

In fact, this file has been created using following piece of code: exitcode = Runtime.getRuntime().exec(cmdline).waitFor();. I assume that the waitFor() method waits for the entire process to be finished, which means that the according file has been written completely and its handle has been released.
2

I see no issues in your code.

Seemingly closing the BufferReader ensure the file is closed. (cf this response).

Maybe you can give a try to Files.delete cf this response.
It will give more information about the deletion fail by throwing different exceptions.

Comments

0

Good afternoon, I would like to thank you all for having searched for a solution of this problem. Unfortunately the problem is not Java based: the file I'm trying to write to is created by a redirection cmd /c <program>.exe >> <output>.log, and it seems that Windows has not fully flushed the output buffer towards the output file, creating the problem.

I am currently using following (very dirty) work-around for this issue:

boolean bFile_can_be_opened = false;
while (!bFile_can_be_opened) {
  try {
    fwLog2 = new FileWriter(sLp_LogFile, true);
    bFile_can_be_opened = true;
  }
  catch (Exception e)
  {}
}

Further information on this issue can be found under the following new StackOverflow question: How to release a file, locked by the application, in Java

Comments

0

I'm a beginner, I do not know as much things as you. But if I am right you should save your changes first a temp file. Afterwards you will read again the temp file and later you'll write to your real file. I hope my comment will help you.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.