0

i have wrote a small piece of code that can be summarized as

Thread() {
 run() {
  BufferedWriter fileout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(log, true), "UTF-8"));;
  while (true) {
    fileout.write(blockingQueue.take());
  }
 }
}

now, some other threads will produce rows and add them to blockingQueue. now, if i remove the file from console, the fileout.write doesn't fail nor throw exceptions.

I was wondering how i can re-open the file if someone remove the file from filesystem via rm logfile.txt from console.

The problem is not how to reopen it, but how to detect that the file was removed.

Some options are 1.do take() and save it to a string 2. open the file and write to it

but even if i change the code in this way, it doesn't guarantee that the file get written before someone remove it.

The other option is to lock the file, but i don't want to do that. I don't want to avoid the delete of the file :)

rama
  • 5
  • 2
  • Here some explanations why it is possible to remove the file in one session whereas a second session keep it still open. [what-happens-to-an-open-file-handler-on-linux-if-the-pointed-file-gets-moved](http://stackoverflow.com/questions/2028874) / [why-can-one-remove-rename-open-files-in-linux](http://stackoverflow.com/questions/16712638) / [moving-a-file-while-its-in-use-how-does-it-work](http://superuser.com/questions/251129) – SubOptimal Apr 23 '15 at 07:43
  • 1
    If you are on a Unix system your code will be dealing with the file through a handle of some kind. Someone else removing the file will remove the entry from the directory but it does not remove the reference held by your program through the open stream. When you close the stream that will flush it's contents into the file and release the handle. The file will then dissappear because no references still exist. The only way I can see of writing to a new file is to close it each time and reopen it. – redge Apr 23 '15 at 14:20

1 Answers1

0

If the file you are writing to can disappear, your best option is to not keep the stream open, but recreate a fresh FileOutputStream whenever you need to write something. That will recreate the file, too (which I suppose is what you want).

Or you could check if the file exists before each write. I suppose that performance-wise the two methods come to about the same.

If performance is an issue, you could buffer in memory and when the buffer is full, open the FileOutputStream (and immediately close it again after writing out the buffer).

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • writing the data into memory will lead to problem if the application crash or is stopped (i can always write a shutdown hook or something but won't catck sigkill if my memory doesn't fail me). Opening a new FileOutputStream will only reduce the issue i presume, it's not "synchornized" if i do open / write /close and between open / write/close there is an rm on console, i will still have the issue. – rama Apr 23 '15 at 08:08
  • You say it is okay if the file gets deleted (you don't want to prevent that), so why is it so important to prevent exposure to even a second of data loss? If someone deletes the file a minute later, it will all be gone anyway, no? – Thilo Apr 23 '15 at 08:54