1

There is some API that allows checking if a file is locked or opened by another program, so my process cannot write to that file.

e.g. we can use this:

File f = new File("some-locked-file.txt");
System.out.println(f.canWrite()); // -> true
new FileOutputStream(f); // -> throws a FileNotFoundException

But there is no guarantee this will work in 100% of cases.

For instance, on my Windows machine if I'm trying to check .csv file, it works as expected - when I open .csv file by another program, my Java code will throw FileNotFoundException, but there is no exception for plain .txt file opened with simple Notepad.

Is there any easy way to check if a file is locked with 100% sureness?

My program exec example.

Community
  • 1
  • 1
ikos23
  • 4,879
  • 10
  • 41
  • 60
  • 1
    "*when I open .csv file by another program, my Java code will throw FileNotFoundException*" .. Are you really sure that FileNotFoundException is thrown? I doubt that. – hagrawal7777 Mar 05 '18 at 14:50
  • @hagrawal it's a reference to this answer https://stackoverflow.com/a/1500521/133203 – Federico klez Culloca Mar 05 '18 at 14:55
  • 1
    I'm pretty sure the answer is "No". Maybe your problem is due to *another* application you're using to open your file somehow lock the file in the manner that OS can recognize it's locked. – zlakad Mar 05 '18 at 14:55
  • @hagrawal added screenshot - I just opened the file with Excel and ran the program afterward. if I close the Excel and run again - no error. Does that mean I am sure about that ?) – ikos23 Mar 05 '18 at 14:58
  • 1
    There is always a race condition, which is most probably not, what causing you problems, but the moment you checked, it might not be locked, but immediately after. Of course the time slice is most of the time very small, and chances that the GC just kicks in in between are low. – user unknown Mar 05 '18 at 15:02
  • `f.canWrite()` followed by `new FileOutputStream(f)` is [a TOCTOU bug](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use). The `f.canWrite()` check is worse than useless - it can change, and it doesn't tell you the `FileOutputStream` can be created. Don't do it. Checking for X before you do Y is always a bad idea. X is never definitive about whether or not Y will work because one, conditions can change, and two, **X isn't Y**. So you have to handle errors from Y anyway. Just do Y and handle the errors. – Andrew Henle Mar 05 '18 at 16:18
  • @AndrewHenle The example that I provided - does not mean I actually do like that ) It's just what is allowed out-of-the-box. The whole question is about how to do that correctly. – ikos23 Mar 05 '18 at 17:05
  • @FedericoklezCulloca there is actually the same question, but no answer. I would like to figure out if there is a way to make it. If there is no API Java provides, maybe there are some external libs or workarounds how to easily make it work. – ikos23 Mar 05 '18 at 17:09

1 Answers1

1

This turned out to be an interesting question and I tried a couple of things myself and below are my observations:

  • Whether java.io.FileNotFoundException: C:\E_Drive\him.csv (The process cannot access the file because it is being used by another process) will not thrown or not will depend upon the editor which has opened the file.
  • If you open a txt file in notepad/notepad++ then new FileOutputStream(file); will not throw the exception but if you open same txt file from an excel then new FileOutputStream(file); throw the exception.
  • My best guess is that probably with software like excel, excel will lock the file and indicate the same to OS and so OS indicate the same to JVM and hence JVM throws the exception, but this doesn't happen with software like notepad/notepad++.

So, I think really answer to your question is "it depends".

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70