2

Firstly, I have checked java.io.IOException: The process cannot access the file because another process has locked a portion - when using IOUtils.copyLarge() in Windows. My question is not about finding whether a file is open or not.

I have a Java application A that is writing log files to the disk. At a given time, there are a large number of files that are written and closed by the A, and few files which are still open, and are being written by A.

I have this second Java application B, which need to read the logs sometimes, and it does. But the problem is, in case the file is open by A, B will spill the error java.io.IOException: The process cannot access the file because another process has locked a portion.

The code that reads the file from B looks like this:

void readFile(Path filePath) {
    FileInputStream fis = new FileInputStream(filePath.toFile());

    byte[] buffer = new byte[1024]
    for (int len; (len = fis.read(buffer)) != -1) {
        // do things with the read bytes
    }
}

I have no control over application A's code. Neither can I determine when application A will release the file. It could be 24+ hours. So I need B to read the file while it's open (if it can be done at all).

I can, however change B's code. Is there any way I can change the above code such that B can read the contents of the locked file? Note that B only needs read access to the files.

sampathsris
  • 21,564
  • 12
  • 71
  • 98
  • why not check before reading the file if that is locked already? or in other words read only when not locked. – Naman Sep 13 '17 at 04:34
  • @nullpointer: The problem is, I cannot determine when application *A* will release the file. It could be 24+ hours. So I need *B* to read the file while it's open (if it can be done at all, hence this question). – sampathsris Sep 13 '17 at 04:40
  • The other way, you can make B look for when is the file open to read and then access. (Since you said A can't be managed by you.) – Naman Sep 13 '17 at 04:41
  • @nullpointer: B needs to run at specific intervals too. It cannot wait. Weird requirements, I know. – sampathsris Sep 13 '17 at 04:43
  • If B needs to run at specific intervals and also know that A is not reading the file at that time, it seems to me a Publisher-Subscriber implementation where you're not able to make `A` a publisher either. Not very sure if I could help you with that, sorry. – Naman Sep 13 '17 at 04:46
  • 1
    @Krumia: it sounds like you are working on a malware :D – A.Shaheri Sep 13 '17 at 04:48
  • @A.Shaheri: I wish I was doing that instead of this. I am actually trying to collect server logs written by Oracle WebLogic. – sampathsris Sep 13 '17 at 04:50
  • Clearly this is Windows, and that's how Windows behaves. I would question the problem statement. Log files are for humans, not for applications. If you want the webapp to communicate something to another application, have it write to a database, a message queue, a socket, ... – user207421 Sep 13 '17 at 04:58
  • @EJP: I want to collect the logs, compress and bundle them, and then send them off to several humans working elsewhere to look at. Hope that make sense :) – sampathsris Sep 13 '17 at 05:04
  • @KrumiaTry using `FileChannel` instead of `FileInputStream`. – Indra Basak Sep 13 '17 at 05:09
  • Thanks @IndraBasak, but would it require that both applications are using the same `FileChannel`? – sampathsris Sep 13 '17 at 05:11
  • @Krumia It should. Please refer [here](https://stackoverflow.com/questions/4149/how-do-i-use-java-to-read-from-a-file-that-is-actively-being-written) – Indra Basak Sep 13 '17 at 05:21
  • Well you can't collect log files that are still being written, and trying to do so doesn't begin to make sense. If you get this error, skip the file and try it again later. @IndraBasak Using `FileChannel` will not solve this problem, because Windows won't let you solve it. – user207421 Sep 13 '17 at 05:39
  • Thanks @EJP! @Krumia If your case has to do with log files and you are using `Log4J`, then you should use `RollingFileAppender`. A rolling file appender will backup log files when they reach a certain size. Then you can read from the backup files. – Indra Basak Sep 13 '17 at 06:01

0 Answers0