Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进程无法访问该文件,因为其他进程正在使用该文件。(文本文件将不会关闭)_C#_.net_Streamreader_Streamwriter - Fatal编程技术网

C# 进程无法访问该文件,因为其他进程正在使用该文件。(文本文件将不会关闭)

C# 进程无法访问该文件,因为其他进程正在使用该文件。(文本文件将不会关闭),c#,.net,streamreader,streamwriter,C#,.net,Streamreader,Streamwriter,在上次重新启动电脑时,此代码块检查后,我试图写入文本文件。下面的代码读取上次重新启动电脑时的文本文件,并从中确定是否显示闪屏。但是,在这个方法运行之后,我需要将当前的“系统启动时间”写入文本文件。但我一直收到一个错误,说文本文件正在使用中。这让我发疯了。我已确保所有StreamWriter和StreamReader都已关闭。我试过使用语句。我试过GC收集。我觉得我什么都试过了 任何帮助都将不胜感激 private void checkLastResart() {

在上次重新启动电脑时,此代码块检查后,我试图写入文本文件。下面的代码读取上次重新启动电脑时的文本文件,并从中确定是否显示闪屏。但是,在这个方法运行之后,我需要将当前的“系统启动时间”写入文本文件。但我一直收到一个错误,说文本文件正在使用中。这让我发疯了。我已确保所有StreamWriter和StreamReader都已关闭。我试过使用语句。我试过GC收集。我觉得我什么都试过了

任何帮助都将不胜感激

    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); }
        }
    }               

在创建
sr2
的地方,
sr
仍然打开settings.txt。

您的编写代码应该以这种方式更改

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类的静态方法。但最重要的是,在创建流之类的一次性对象时,请确保使用正确关闭文件

完成回答您的评论。在代码的第一部分也使用语句

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
}

在关闭
else
块中的第一个实例之前,您正在打开第二个版本的
StreamReader
。Thank You@entropic的可能重复就是问题所在!我很困惑,因为我在if语句打开后立即关闭了StreamReader。为什么我需要再次关闭它?此外,如果在if语句关闭之前sr实际上没有关闭,为什么它允许我打开StreamWriter的实例来访问该文件?你是什么意思?如果您在
else
块中,那么
If
块中的任何内容都不会执行-因此您永远不会真正关闭第一个
StreamReader
…@熵哦,没错!我懂了。谢谢你指出这一切。我希望我对那些愚蠢的错误有更好的眼光。希望我能通过练习变得更好。这不是我实际问题的正确答案;但是,对于等待发生的错误,这是正确的解决方案。(这是在我修复了之前执行的代码块中的初始错误之后发生的)。这不是我实际问题的正确答案;但是,对于等待发生的错误,这是正确的解决方案。我得到的错误的实际解决方案是,我没有在“if语句”完成后关闭StreamReader sr。我很困惑,因为我确实在if语句打开后立即关闭了sr,但它也需要在if语句完成后关闭。在我修复了之前执行的代码块中的初始错误之后,您所说的错误发生在我身上。非常感谢:)我明白了,使用的另一个原因有助于避免这种复杂的情况。我对c相当陌生,从我收集的信息来看,使用语句基本上是在设定范围内使用对象/方法/等的一种方式?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
}