Reputation: 113
I saw both of these questions:
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
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
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.
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
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