IO 异常 - 另一个进程正在使用文件(创建目录后无法打开文件)

IO Exception - File being used by another process (Can't open file following directory creation)

我有一个项目正在进行中,可以在患者接受手术时为兽医监测他们,并将结果写入文本文件。当我尝试输出时,我只是让文件保存在 Debug 文件夹中,效果很好。但是,我现在创建了一个完整的目录,用于创建或打开一个主文件夹,然后是一个子文件夹(基于程序的输入文本),用于将文本文件保存到其中。

    private void createDirectory()
    { //create output file in this folder using owner name and current date

        //main folder path (contains all files output from system)
        string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\Horse Monitoring Records";
        //sub folder path (each patient has individual subfolder)
        string subDirectory = rootDirectory + "\" + txtPatName.Text + "-" + txtOwnerName.Text;
        //file name (patient has file created for each operation)
        fileName = subDirectory +  "\" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("ddMMyyyy") + ".txt";

        if (!Directory.Exists(rootDirectory)) //if main folder does not exist...
        {
            Directory.CreateDirectory(rootDirectory); //create it in My Documents
        }
        if (!Directory.Exists(subDirectory)) //if patient sub folder does not exist...
        {
            Directory.CreateDirectory(subDirectory); //create it in Patient-Owner format
        }
        if (!File.Exists(fileName)) //if monitoring file does not exist...
        {
            File.Create(fileName); //create it in Owner-Date format
        }
    }

这个阶段工作正常,但是一旦您尝试将一些数据保存到文本文件中,它就会抛出 运行 时间错误,指出

The file cannot be accessed because it is being used by another process.

此处出现异常:

    private void saveFileDetails()
    {
        //Once case details have been entered, create new file using these details and add data input structure
        StreamWriter consoleFile = new StreamWriter(fileName);
    ...
    }

当我去查看文件夹时,相关的子文件夹和文件已经创建,但文本文件是空白的。 我猜这与创建目录后关闭文本文件有关,这意味着当系统尝试打开它时它已经打开了。不过我不知道如何解决这个问题!

上面显示的两个函数是这样调用的:

    private void btnStart_Click(object sender, EventArgs e)
    {
        ...

        //file details entered upon load written to new file - according to PatID
        createDirectory();
        saveFileDetails();
    }

任何关于从这里去哪里的建议都将不胜感激!

谢谢, 马克

StreamWriter 实现了 IDisposable,因此将它包装在一个 using 块中可以管理关闭和处置编写器并确保它在您下次要触摸该文件时可用。如果文本文件不存在,它还可以管理创建文本文件,从而无需显式调用 File.Create.

StreamWriter consoleFile = new StreamWriter(fileName);

变成

using (StreamWriter writer = File.AppendText("log.txt"))
{
    // writing, etc.
}

using (StreamWriter writer = new StreamWriter(fileName, true))
{ // true says "append to file if it exists, create if it doesn't"
    // writing, etc.
}

任何你觉得更易读的都可以。

这里的问题是你这样做

if (!File.Exists(fileName)) //if monitoring file does not exist...
{
    File.Create(fileName); //create it in Owner-Date format
}

就在您尝试写入文件之前。因为您刚刚创建了它(如果它不存在),操作系统可能还没有释放该文件。

就像评论中提到的@Jauch,您可以完全跳过此检查并使用 StreamWriter 重载,如果文件不存在则创建文件,如果文件存在则附加到文件。

private void saveFileDetails()
{
    //Once case details have been entered, create new file using these details and add data input structure
    using (StreamWriter consoleFile = new StreamWriter(fileName, true))
    {
        // ...
    }
}

或者,您可以使用以下方式一次编写所有文本:

File.AppendAllText(textToWrite, fileName);

File.Create(fileName) returns 永远不会关闭的文件的打开流。

要创建空文件,请使用 File.WriteAllBytes(fileName, new byte[0]);

否则2个方法可以缩短

private void SaveFileDetails()
{
    string subDirectory = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
        "Horse Monitoring Records");

    // create the folder hierarchy if not exists. does nothing if already there
    Directory.CreateDirectory(subDirectory);

    // each patient has individual file
    var filepath = Path.Combine(subDirectory,
        txtPatName.Text + "-" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt");

    // creates the file if not exists
    using (var writer = new StreamWriter(filepath, append: true, encoding: Encoding.UTF8))
    {
        // write details
    }
}

注:

  • 合并了 2 个方法
  • .NET 命名约定已应用
  • 更改了日期格式以便在资源管理器中更好地按名称排序