BinaryReader或Writer.Close()没有正确关闭C#

时间:2012-05-11 08:57:19

标签: c# filestream binaryreader binarywriter

我有一个表单应用程序,它执行模拟并不断读取/写入二进制文件。如果让它通过,一切正常。但是,如果表单已关闭/模拟已中止,则文件流未正确关闭 - 文件将被锁定。 有没有办法确保所有流关闭?我尝试了以下 - 但它没有效果...... 非常感谢提前, Ť

        public BinaryWriter BinWrite;
        public BinaryReader BinRead;

        public BinaryWriter EnvBinWrite;
        public BinaryReader EnvBinRead;       

public void theForm_FormClosing(object sender, FormClosingEventArgs e)
        {

            //Close all binary file reader/writers -- crashes if it cannot overwrite files
            foreach (Building B in AllBldgs)
            {
                try
                {
                    EnvBinRead.Close();
                }
                catch
                { continue; }
                try
                {
                    EnvBinWrite.Close();
                }
                catch
                { continue; }
                try
                {
                    BinRead.Close();
                }
                catch
                { continue; }

                try
                {
                    BinWrite.Close();
                }
                catch
                { continue; }
            }
        }

3 个答案:

答案 0 :(得分:7)

您确定知道continue关键字的用途吗?请注意,这将继续下一个循环,而不是下一个代码块。因此,如果关闭EnvBinRead时发生异常,您将输入要关闭EnvBinWrite的块,但继续AllBldgs中的下一项。

要吃掉所有异常并仍然尝试关闭所有二进制编写器,你可以写:

foreach (Building B in AllBldgs)
{
    try
    {
        EnvBinRead.Close();
    }
    catch (Exception exp)
    { 
        Console.WriteLine("Closing EnvBinRead failed!" + exp.ToString());
    }

    try
    {
        EnvBinWrite.Close();
    }
    catch (Exception exp)
    { 
        Console.WriteLine("Closing EnvBinWrite failed!" + exp.ToString());
    }

    try
    {
        BinRead.Close();
    }
    catch (Exception exp)
    { 
        Console.WriteLine("Closing BinRead failed!" + exp.ToString());
    }

    try
    {
        BinWrite.Close();
    }
    catch (Exception exp)
    { 
        Console.WriteLine("Closing BinWrite failed!" + exp.ToString());
    }
}

请注意,仅仅吃掉例外从不是一个好主意。如果您不关心阅读器或写入是否可以关闭,请在关闭之前检查它是否已初始化,如评论中所示。

答案 1 :(得分:2)

你应该调用dispose来关闭BinaryReader和Writer。

<强>解释

当你在它们上面调用Dispose时,

StreamReader, StreamWriter, BinaryReader and BinaryWriter都会关闭/处置它们的基础流。如果读取器/写入器只是垃圾收集,它们不会丢弃流 - 您应该始终处理读取器/写入器,最好使用using语句。 (事实上​​,这些类都没有终结器,也不应该有终结器。)

我个人更喜欢为流提供一个using语句。您可以非常巧妙地使用没有大括号的语句进行嵌套:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

即使流的using语句有点多余(除非StreamReader构造函数抛出异常),我认为如果你摆脱StreamReader和只需在以后直接使用流,您就已经拥有了正确的处理语义。

答案 2 :(得分:1)

对流使用“使用块”总是好的,使用后立即关闭它们。