13

Is there a way I can check if a file is in use or is not opened by other process without just trying to open it and catching an exception? Is there no service method to test such a thing?

CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
  • 6
    Well, why would you want to know? To open the file afterwards anyway? Then you can skip the check and try directly because you could get a race anyway. – Joey Mar 12 '13 at 13:26
  • @Јοеу not neccessary but mostly its the reason, but once a 3rd party tool is involved it would be helpful to determine if the file can be opoened or not beore calling the open method of the 3rd party, anyway it i would expect to hace such a methode and not to be implement the catch statement as art of the plan. – CloudyMarble Mar 12 '13 at 13:31
  • possible duplicate of [How to check if a file is already open by another process in C?](http://stackoverflow.com/questions/1951791/how-to-check-if-a-file-is-already-open-by-another-process-in-c) – David Heffernan Mar 12 '13 at 13:50
  • This is not a duplicate, the main point here is the attempt by try catch and not generally if it is possible or not. – CloudyMarble Mar 12 '13 at 13:54
  • If Hal's C answer (not the marked as answer one) corresponds to what you need in David's link, you have a .NET P/Invoke IsFileInUse equivalent here: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/dead0507-06f5-43e0-9250-a78437956bc8 – Simon Mourier Mar 12 '13 at 14:18

4 Answers4

15

Even if there was, it wouldn't do you much good since you would still have to catch the exception in order to handle the race condition where the file became unavailable in between your initial check and your actual attempt to open/access it.

I can't think of any compelling advantage to a preliminary defensive check. It just results in unnecessary code duplication.

If there were such a IsFileAccessible function, it would probably be implemented as a giant try/catch block that attempted to open the file, caught failures, and returned the result.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • @CodyGray Thnx for answering, but is'nt this the same like checking the access control of a file which can be changed in between until i access it? but i do have this option to ask these access controls without having to run into a catch statement, it can still happen but then it wouldnt be part of my plan. – CloudyMarble Mar 12 '13 at 13:37
  • 1
    You're right. But, although you can't avoid checking exceptions in the end, it still could be interesting to have a function that checks that without necessarily opening the file. Some useful tools do give that information, and they are not based on try/catch code. – Simon Mourier Mar 12 '13 at 13:37
  • @SimonMourier It's trivially easy to do it without try/catch. Just call `CreateFile`. – David Heffernan Mar 12 '13 at 13:39
  • @DavidHeffernan - right, so why don't you give that as an answer then? – Simon Mourier Mar 12 '13 at 13:40
  • @Simon Because I think the spirit of the question is not actually about exceptions. I think it is "Can I test if a file can be opened without attempting to open it?" I think the error handling mechanism is beside the point. – David Heffernan Mar 12 '13 at 13:41
  • @DavidHeffernan thats exactly the question, i changed the title to exactly what you wrote. – CloudyMarble Mar 12 '13 at 13:45
  • @DavidHeffernan - I don't understand it the same as you. – Simon Mourier Mar 12 '13 at 13:47
  • @SimonMourier Well, TwoMore has clarified what he meant now – David Heffernan Mar 12 '13 at 13:47
  • @CodyGray But you agree that try catch statements were not designed for this but for real unexpected issues do'nt you. – CloudyMarble Mar 12 '13 at 13:51
  • 1
    It's irrelevant whether or not you catch an exception. The point is that the only way to actually know if you can open a file is to try and open it. Before exceptions were invented (and still in languages that do not support them), the `OpenFile` function (or equivalent) simply returned an error code indicating either success or a specific error condition: `FileNotFound`, `FileInUse`, `UnauthorizedAccess`, etc. @two – Cody Gray - on strike Mar 12 '13 at 13:53
  • The best practice is to throw exceptions on exceptional cases. I think that one should check if the file is accessible, than open it, but still have a catch block for the case where the conditions change between checking and the actual open. – jaraics Mar 31 '14 at 08:09
  • @jar Redundant code is harder to maintain. You're only making your life more difficult. Think about it this way: are you going to respond differently in the two cases? I can't imagine why. Either way, the file couldn't be opened. The point is that since you have to handle the error/exception *anyway*, why make things harder on yourself? – Cody Gray - on strike Mar 31 '14 at 16:52
3

Can I test if a file can be opened without attempting to open it?

The .net framework, just like the Windows API beneath, provides no such functionality. If you wish to know whether or not a file can be opened you are expected to attempt to open it and check for failure.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

Interesting way to avoid try catch (but implies an attempt to open) is the LockFile() or CreateFile() functions:

HANDLE WINAPI CreateFile(...)

If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.


BOOL WINAPI LockFile(...)

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). To get extended error information, call GetLastError.

This locks the specified file for exclusive access by the calling process, and on failure writes error information to the thread's last-error, which can be retreived using the GetLastError function.

It would still be thinkable that between the unlockFile and OpenFile another process could lock the file, but it possible to minimize this period by keeping the file locked just to the moment it needs to be opened.

CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
  • 1
    Ask yourself where hFile comes from? – David Heffernan Mar 13 '13 at 08:28
  • Your right! I ended with CreateFile, although it doesnt throw an exception and enables readbale return value it still an attempt to open the file – CloudyMarble Mar 13 '13 at 10:12
  • 1
    That's exactly what I and others have been telling you. It so happens that the .net mechanisms for opening files signal failure with exceptions. The Win32 mechanisms signal error through the return value. Fundamentally it comes to the same in the end. – David Heffernan Mar 13 '13 at 10:21
  • @DavidHeffernan ya some need to go the long way to understand it, thank you. But could'nt .net go all running processes to check if any is locking the file, and provide this as such File function? am i missing anything? – CloudyMarble Mar 13 '13 at 10:45
  • Windows simply doesn't provide a mechanism to do that beyond attempting to open the file – David Heffernan Mar 13 '13 at 11:29
  • 1
    @TwoMore Maybe the operating system *could* do that (although like David says, it doesn't), but as I explained in my answer, it wouldn't serve a useful purpose if it did. Code like this: `if (FileExists(file)) { OpenFile(file); }` is *fundamentally broken* because it doesn't handle the case where the file goes missing between the call to `FileExists()` and `OpenFile()`. So you might as well just try to open the file and handle any errors that result (whether from an exception or from a return code). My answer discussed exceptions because of the tags you applied to your question. – Cody Gray - on strike Mar 13 '13 at 23:28
0

You could implement this guy in .net 4.5 but it includes a lot of overhead http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

Kimate Richards
  • 150
  • 1
  • 7