TnD_Guy
TnD_Guy

Reputation: 113

Using C# to check if a file is in use

I saw both of these questions:

Check if file is in use

Is there a way to check if a file is in use?

And neither of them provided me all of the info that I needed, and I needed more clarification on some of the answers, but the questions were several years old, so I wasn't sure if I should try to get responses from there at this point.

So I posted a new question. Something like

public string myFile;
myFile = @"C:\somepath\somefile.pdf";

if (myFile isinuseorwhatever)
{
     MessageBox.Show("File is in use!! Close it and try again");
     return;
}
else
{
     MessageBox.Show("That worked. Good job!")
     //Do Stuff and lots of lines of stuff.
}

I can do this using exception handling, but the issue is that I need to do the check before I run the many lines of code.

I have a feeling that I need to make a class to check it, then run that class. To be honest, I'm pretty new to coding so I'm not 100% clear on how classes work.

I know about using try and catch, but that won't work here because the exception is happening in the last few lines of code in the try block, so all of that stuff will happen before it hits the exception. Like, this program copies a file, renames it, moves it into a different directory, and then deletes the original, which is the last thing it does. If a user has the file open, it will do all of that but then throw an exception when it tries to delete. I need it to throw the exception BEFORE it copies, renames, moves and so on.

Upvotes: 3

Views: 16909

Answers (3)

Gian Paolo
Gian Paolo

Reputation: 4249

Current @code-pope accepted answer includes within a try-catch too much code, it consider every exception happened as "the file is in use", while actually an exception can rise also for other reasons

I would do something like this:

string path = "some path";
FileStream fs = null; 
try
{
    fs = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch(Exception ex)
{
    //ops, cannot open file, better not keep on
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}

// lets go on now...
using (fs)
{
    // do your work
}

Upvotes: 2

Code Pope
Code Pope

Reputation: 5449

You can get lock a file for exclusive access by using FileStream with FileShare.None. So if we want to implement the first requests mentioned i.e.

  1. check if the file is in use, if yes, inform the user
  2. if not lock it, so no one opens it
  3. copy the file
  4. rename the file

You can implement the following code:

try
{

    using (Stream stream = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
    {
        // Here you can copy your file
        // then rename the copied file
    }
}
catch (Exception ex)
{
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}

I think you know how to copy and rename the file (if not comment it and I will add the code here). The second part of your question is a little bit tricky. Because you cannot use Filestream to delete a file. A soon as you dispose the filestream to call File.Delete("YourFile.doc") it is possible that some accesses it exactly in that moment. I would recommend that you truncate the file when it is locked, so that it unusable for other users. You can also keep your process in a loop until the file is released. The code would look like that:

try
{
    using (Stream stream = new FileStream("1.docx", FileMode.Open, FileAccess.ReadWrite, FileShare.None))
    {
        // Here you can copy your file
        // then rename the copied file
        using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
        {
            writer.Write(""); // truncate the file, making it unusable to others
        }
    }
    while (true)
    {
        try
        {
            File.Delete("1.docx");
        }
        catch 
        {
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show("File is in use!! Close it and try again");
    return;
}

Upvotes: 5

Dejan
Dejan

Reputation: 113

Use a bool value and set it to false if an exception is thrown when trying to open the file.

Example:

    string path = "Your Path";
    bool available = true;
    try
    {
        using (FileStream fs = File.Open(path, FileMode.Open))
        {

        }
    }
    catch(Exception ex)
    {
        available = false;
    }

Upvotes: 1

Related Questions