File.OpenWrite gives error while FileStream(sFile, FileMode.Open, FileAccess.ReadWrite) does not

StackOverflow https://stackoverflow.com/questions/23402532

  •  13-07-2023
  •  | 
  •  

Question

I have the following code to detect if a file is already in use or not:

public static bool FileInUse(string sFile)
{
    FileStream file = null;

    try
    {
        file = new FileStream(sFile, FileMode.Open, FileAccess.ReadWrite);
        file.Close();

        file = File.OpenWrite(sFile);
        file.Close();

        return false;
    }
    catch (Exception)
    {
        try { file.Close(); }
        catch (Exception) { }

        return true;
    }
}

When the file is in use then, new FileStream(sFile, FileMode.Open, FileAccess.ReadWrite) does not throw error but File.OpenWrite(sFile) throws error:

The process cannot access the file because it is being used by another process.

Why is that? Because I want to check if a file can be opened in write mode.

Was it helpful?

Solution

The constructor you are using for FileStream defaults to sharing mode FileShare.Read, meaning that later requests to open the file for reading (but not writing) will be allowed. This will work even when the file is already open for reading (if that is not exclusive reading).

On File.OpenWrite, MSDN online states:

This method is equivalent to the FileStream(String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None.

http://msdn.microsoft.com/en-us/library/system.io.file.openwrite(v=vs.110).aspx

This means that File.OpenWrite tries to get exclusive Read access to the file, not only exclusive Write access.

It sounds like when you test your file for "in use" it is open for reading.

Both methods check that the file is available for exclusive writing. You need to decide if your application also requires exclusive reading.

OTHER TIPS

Because

File.OpenWrite(sFile) -> return new FileStream(path, FileMode.OpenOrCreate,
                                  FileAccess.Write, FileShare.None);

but

public FileStream(String path, FileMode mode, FileAccess access) : this(path, mode, access, FileShare.Read, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false) { }

As you can see the first one uses FileShare.None, but second uses FileShare.Read

From MSDN:

FileShare.None Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.

FileShare.Read Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.


A little off-topic, but: there is no very good way to check if file is in use or no, because in the fraction of time between your call to the FileInUse method and your call to open file, this file may get locked again. This FileInUse method is ultimately redundant. You can just catch exceptions when your try your exclusive access to file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top