我有一个表单应用程序,它执行模拟并不断读取/写入二进制文件。如果让它通过,一切正常。但是,如果表单已关闭/模拟已中止,则文件流未正确关闭 - 文件将被锁定。 有没有办法确保所有流关闭?我尝试了以下 - 但它没有效果...... 非常感谢提前, Ť
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; }
}
}
答案 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)
对流使用“使用块”总是好的,使用后立即关闭它们。