0

I'm writing a logger to my java program (in csv format). The logger works fine, and I had one problem.

It sounds pretty logical that the program will crash when i tried to write to the file and at the same time open the file. When i do that, I got that exception: "The process cannot access the file because it is being used by another process".

My question is if there is anyway to continue writing even if someone open the file?

Thanks.

UPDATE:

I think i solved the problem. Every time after i write to the file (With bufferedWriter and FileWriter), I call to a close() function that closing the bufferedWriter and FileWriter.

I changed the close() function: 1. Added fileChannel and FileLock. 2. Igonore the line bw.close();

Its ok not to close the bufferWriter (bw)?, Can there be any problems later on?

private void close() throws IOException {
    RandomAccessFile rf;
    rf = new RandomAccessFile(file, "rw");
    fileChannel = rf.getChannel();
    lock = fileChannel.lock();
    try {
        if (bw != null) {
            //    bw.close();  The line i ignored.
            bw = null;
        }
        if (fw != null) {
            fw.close();
            fw = null;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    lock.release();

}

UPDATE 2: Now i found that if i change the function to that (close changed to flush), Its working:

   private void close()  {
    try {
        if (bw != null) {
            bw.flush(); 
            bw = null;
        }
        if (fw != null) {
            fw.flush();
            fw = null;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

What is the best option ?

Idon89
  • 141
  • 4
  • 16

3 Answers3

1

Is there is anyway to continue writing even if something else has opened the file?

Not in Java.

To write a file, you must first open it. If you cannot open it because the OS won't permit it ... because something else has opened it ... then you cannot get to the point where you can write it.

In this scenario, you should consider opening a different log file.


Note that this scenario happens in Windows because Java is following normal Window practice and opening the file with an exclusive (mandatory) lock by default. Short of changing Java ... and every other Windows application that opens files like this ... you are stuck.


UPDATE

It turns out that there may be a way.

  1. Read this Q&A: https://stackoverflow.com/a/22648514/139985
  2. Use FileChannel.open as described, but use flags that allow you to write without forbidding other writers. For example

       FileChannel.open(path, WRITE)
    

    or

       FileChannel.open(path, WRITE, APPEND)
    

    The trick is that you don't want any of the NOSHARE_* options.

CAVEAT: I haven't tried this.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

Reverse the problem: try to open while continuing writing:

  • if you want fixed datas, you can copy the file (by shell), and then read it;

  • if you want even future written datas, you must keep the same output: try to redirect the normal output, to something you can store and read.

Perhaps some library exists. It seems like tee and tpipe.

see for example: Could I duplicate or intercept an output stream in Java?

  • for redirecting log4j to what you want, see this for example:

How do I redirect log4j output to my HttpServletResponse output stream?

Community
  • 1
  • 1
1

As @guillaume said, you can use a library like log4j.

But If you want to implements your solution in Java, you can use the observer pattern and write your logs async.

bpedroso
  • 4,617
  • 3
  • 29
  • 34