简体   繁体   English

使用C#检查文件是否正在使用中

[英]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. 老实说,我对编码还很陌生,所以我不是100%清楚类的工作方式。

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. 我知道使用trycatch ,但是在这里不起作用,因为该异常发生在try块的最后几行代码中,因此所有这些事情都会在遇到异常之前发生。 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. 我需要它在复制,重命名,移动等之前引发异常。

You can get lock a file for exclusive access by using FileStream with FileShare.None . 通过将FileStreamFileShare.None使用,可以锁定文件以进行独占访问。 So if we want to implement the first requests mentioned ie 因此,如果我们要实现提到的第一个请求,即

  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. 因为您不能使用Filestream删除文件。 A soon as you dispose the filestream to call File.Delete("YourFile.doc") it is possible that some accesses it exactly in that moment. 一旦您将文件流filestream为调用File.Delete("YourFile.doc")就有可能在那一刻确切地访问它。 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;
}

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 当前@ code-pope接受的答案包含在try-catch中的太多代码,它认为每个异常都发生在“文件正在使用中”的情况下,而实际上由于其他原因也会引发异常

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
}

Use a bool value and set it to false if an exception is thrown when trying to open the file. 如果尝试打开文件时引发异常,请使用bool值并将其设置为false。

Example: 例:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM