该进程无法访问该文件,因为它正在被另一个进程使用.(文本文件不会关闭)

本文关键字:文件 进程 文本 访问 因为 另一个 | 更新日期: 2023-09-27 18:12:03

我正试图在此代码块检查PC上次重新启动后写入文本文件。下面的代码从一个文本文件中读取PC最后一次重启的时间,并从那里决定是否显示一个闪屏。但是,在此方法运行后,我需要将当前的"系统正常运行时间"写入文本文件。但我一直得到一个错误,说文本文件正在使用。这快把我逼疯了。我已经确保所有的streamwriter和streamreader都关闭了。我试过使用语句。我试过GC.Collect。我觉得我什么都试过了。

如有任何帮助,不胜感激。

    private void checkLastResart()
    {
        StreamReader sr = new StreamReader(Path.GetDirectoryName(Application.ExecutablePath) + @"'Settings.txt");
        if (sr.ReadLine() == null)
        {
            sr.Close();
            MessageBox.Show("There was an error loading 'System UpTime'. All settings have been restored to default.");
            StreamWriter sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + @"'Settings.txt", false);
            sw.WriteLine("Conversion Complete Checkbox: 0");
            sw.WriteLine("Default Tool: 0");
            sw.WriteLine("TimeSinceResart: 0");
            sw.Flush();
            sw.Close();
        }
        else
        {
            try
            {
                StreamReader sr2 = new StreamReader(Path.GetDirectoryName(Application.ExecutablePath) + @"'Settings.txt");
                while (!sr2.EndOfStream)
                {
                    string strSetting = sr2.ReadLine();
                    if (strSetting.Contains("TimeSinceResart:"))
                    {
                        double lastTimeRecorded = double.Parse(strSetting.Substring(17));
                        //If the lastTimeRecorded is greater than timeSinceResart (computer has been resarted) OR 2 hours have passed since LVT was last run
                        if (lastTimeRecorded > timeSinceRestart || lastTimeRecorded + 7200 < timeSinceRestart)
                        {
                            runSplashScreen = true;
                        }
                        else
                        {
                            runSplashScreen = false;
                        }
                    }
                }
                sr2.Close();
                sr2.Dispose();
            }
            catch (Exception e) { MessageBox.Show("An error has occured loading 'System UpTime'.'r'n'r'n" + e); }
        }
    }               

下面是运行上述代码后写入Text文件的示例。这并不重要,如果我打开一个StreamWriter,或使用文件。WriteAllLines,立即抛出错误。

StreamWriter sw = new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + @"'Settings.txt");
            string[] lines = File.ReadAllLines(Path.GetDirectoryName(Application.ExecutablePath) + @"'Settings.txt");
            lines[2] = "TimeSinceResart: " + timeSinceRestart;
            foreach (string s in lines)
                sw.WriteLine(s);

该进程无法访问该文件,因为它正在被另一个进程使用.(文本文件不会关闭)

您编写的代码应该这样修改

string file = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"Settings.txt");
// First read the two lines in memory
string[] lines = File.ReadAllLines(file);
// then use the StreamWriter that locks the file
using(StreamWriter sw = new StreamWriter(file))
{
     lines[2] = "TimeSinceResart: " + timeSinceRestart;
     foreach (string s in lines)
         sw.WriteLine(s);
}

这样,StreamWriter上的锁就不会阻塞FileReadAllLines的读取。
说到这里,请注意几点。不要使用字符串连接创建路径字符串,而是使用path类的静态方法。但最重要的是,当您创建一个一次性对象(如流)时,请确保使用using语句正确关闭

文件。

完整回复你的评论。在代码的第一部分也使用语句

private void checkLastResart()
{
    string file = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"Settings.txt");
    using(StreamReader sr = new StreamReader(file))
    {
        if (sr.ReadLine() == null)
        {
            sr.Close();
            MessageBox.Show(...)
            using(StreamWriter sw = new StreamWriter(file, false))
            {
                sw.WriteLine("Conversion Complete Checkbox: 0");
                sw.WriteLine("Default Tool: 0");
                sw.WriteLine("TimeSinceResart: 0");
                sw.Flush();
            }
        }
        else
        {
            ....
        }
    } // exit using block closes and disposes the stream
}

创建sr2时,sr仍然打开settings.txt