3

I need to verify if specific file is open to prevent the copy of that file.

I try lot of examples but any doesn't work! I try, for example, this:

protected virtual bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }

    //file is not locked
    return false;
}

I need orientation... where am I fail? suggestions?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    This is a `Classic problem / Issue` with you declaring the `stream` variable either `Globally` or somewhere else in code where you did not wrap the original creation of the `new` instance in a `using(){}` clause. do a search of all the places you are using `stream` and make sure that you `Dispose(), Close(), and or Flush() & Close the Stream` also could be that the `file.Open()` method needs to be `FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);` – MethodMan Apr 01 '13 at 18:17
  • Why do you need to _verify if [a] specific file is open to prevent the copy of that file_ when you can just try to copy the file and catch any exceptions? – Austin Salonen Apr 01 '13 at 18:20
  • 1
    @DJKRAZE: The code provided effectively implements `using (var stream = file.Open(...)) { ... }` – Austin Salonen Apr 01 '13 at 18:24
  • Are you trying to create a lock, or see if a lock exists? – Joel Coehoorn Apr 01 '13 at 18:52
  • Related: http://stackoverflow.com/questions/265953/how-can-you-easily-check-if-access-is-denied-for-a-file-in-net/265958#265958 – Joel Coehoorn Apr 01 '13 at 18:52
  • My objective is copy automatically a file, but if the file is open I want block this copy... –  Apr 02 '13 at 09:21

2 Answers2

2

If you want to know whether your application already had the file open, you should just save the FileStream in a field, and reset the field to null when you close the stream. Then you can simply test and get the FileStream of the file.

If you want to know whether another application already has the file open, then there is not much you can do. You'll might get an exception when you try to open the file. But even if you knew, then you wouldn't be able to prevent the copy of that file, because you don't have a reference to the file or its FileStream in your application.

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • I think maybe he wants to copy the files himself, and wants to check if each file is open before he copies it. – Matthew Watson Apr 01 '13 at 18:25
  • My objective is copy automatically a file, but if the file is open I want block this copy... –  Apr 02 '13 at 08:44
2

You can suffer from a thread race condition on this which there are documented examples of this being used as a security vulnerability. If you check that the file is available, but then try and use it you could throw at that point, which a malicious user could use to force and exploit in your code.

Your best bet is a try catch / finally which tries to get the file handle.

try
{
   using (Stream stream = new FileStream("MyFilename.txt", FileMode.Open))
   {
        // File/Stream manipulating code here
   }
} catch {
  //check here why it failed and ask user to retry if the file is in use.
}

or

see this another options

https://stackoverflow.com/a/11060322/2218635

Community
  • 1
  • 1
Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
  • In your example (http://stackoverflow.com/a/11060322/2218635) you have "int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1); " explain to me this because c# doesn't know what is Marshal even put on the top of my document "using System.Runtime.InteropServices.Marshal;" –  Apr 02 '13 at 09:04