为什么在 C# 中使用后文件仍然打开

Why file still open after using in c#

在我的代码中,我在 .csv 文件中进行了读写。

 using (StreamWriter file = new StreamWriter(destFile, true))
            {
                string[] lines;
                file.WriteLine("Date,Entity, ProdFamily);
                for (int i = 0; i < numberFile; i++)
                {
                    Console.WriteLine(files[i]);
                    lines = System.IO.File.ReadAllLines(files[i]);
                    foreach (string line in lines)
                    {
                        if (line != lines[0])
                        {  
                            file.WriteLine(string.Format("{0},{1},{2},
                            values[43], values[0], values[3]);
                        }
                    }
                }
            }

之后,我将代码写入 sort 文件的包含部分。

var sorted =
            File.ReadLines(destFile)
                .Select(line => new {
                    SortKey = Int32.Parse(line.Split(',')[4]),
                    Line = line
                })
                .OrderBy(x => x.SortKey)
                .Select(x => x.Line);
            File.WriteAllLines(destFile, sorted);

但是,显示的错误提示我仍然没有 close 我的文件。它说该进程无法访问该文件,因为它正被另一个进程使用。

Exception thrown: 'System.IO.IOException' in mscorlib.dll

我尝试使用using确保文件自动关闭,但错误仍然存​​在。

using 中包含的代码与此处无关,正确关闭文件,第二个代码块有问题 - 枚举 File.ReadLines() 的结果已打开文件进行读取,并且在枚举器关闭之前不会关闭它。因此,您无法在枚举过程中写入同一文件。

您的选择似乎是写入您 File.WriteAllLines() 中与您在 File.ReadLines() 中阅读的文件不同的文件,或者您可以确保枚举在写入之前完成通过在用于初始化 sorted 的最后一个 .Select(...) 之后添加 .ToList() 对数据进行排序,或者您可以一次读取所有行(以便在尝试写入之前再次关闭文件它), 通过使用 File.ReadAllLines() 而不是 File.ReadLines().

您不能同时读取和写入这样的文件。另外,如果您的程序在中途崩溃,这可能不是一个好主意。

容错方法是将新数据写入临时文件,完成后重命名。

var sorted =
        File.ReadLines(destFile)
            .Select(line => new {
                SortKey = Int32.Parse(line.Split(',')[4]),
                Line = line
            })
            .OrderBy(x => x.SortKey)
            .Select(x => x.Line);

var tempFile = Path.GetTempFileName();
File.WriteAllLines(tempFile, sorted);
File.Move(tempFile, destFile, overwrite: true);