File.ReadLine 打开的文件是否在异常时关闭?
Are files opened by File.ReadLine closed on exceptions?
如果在遍历生成的可枚举对象时抛出异常,通过 File.ReadLines
读取的文件是否会关闭?
示例:
File.ReadLines("file.txt")
.Select(line => { throw new Exception(); return 1; });
file.txt
曾经关闭过吗?
而如果确实关闭了,迭代不继续的事实又是如何由实现决定的呢?
我无法理解文件如何关闭的原因如下。我怀疑 ReadLines
实现是这样的:
IEnumerable<string> ReadLines(string file)
{
using (var reader <Open reader>)
{
String line = null;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
如果在迭代期间抛出异常,则不会从生成的枚举器中获取所有行。然后 while
-statement 之后的行永远不会到达并且 using
-statement 将没有机会关闭流。
是的,它将被关闭。它在内部通过 FileStream 创建一个 StreamReader 并在 using 块中使用它。
我不确定你在第二个问题中的意思(你可以简单地捕获异常)。
当使用 foreach
的枚举被中止时,枚举器将被丢弃。在 "early dispose" 的情况下,C# 迭代器方法执行所有活动的 finally 块。这意味着迭代器方法内的所有 using
语句都被接受,因为 using
基于 finally
.
为了使其更具体:Dispose
只能在 yield return
语句中的 C# 生成的枚举器上调用。只有 yield return
将控制权交给调用者。
生成的状态机跟踪在每个屈服点激活的 finally 块,并在 Dispose
方法中执行它们。
如果您简单地放弃一个枚举器 (File.ReadLines("file.txt").GetEnumerator();
),finally 块将不会被接受。没有机制可以做到这一点。
TL;DR:只要您处置最外层的枚举器和链中的所有枚举器(此处:Select
和 ReadLines
)正确处置它们的内部,文件在所有情况下都会被关闭使用 finally
.
的枚举器
如果在遍历生成的可枚举对象时抛出异常,通过 File.ReadLines
读取的文件是否会关闭?
示例:
File.ReadLines("file.txt")
.Select(line => { throw new Exception(); return 1; });
file.txt
曾经关闭过吗?
而如果确实关闭了,迭代不继续的事实又是如何由实现决定的呢?
我无法理解文件如何关闭的原因如下。我怀疑 ReadLines
实现是这样的:
IEnumerable<string> ReadLines(string file)
{
using (var reader <Open reader>)
{
String line = null;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
如果在迭代期间抛出异常,则不会从生成的枚举器中获取所有行。然后 while
-statement 之后的行永远不会到达并且 using
-statement 将没有机会关闭流。
是的,它将被关闭。它在内部通过 FileStream 创建一个 StreamReader 并在 using 块中使用它。 我不确定你在第二个问题中的意思(你可以简单地捕获异常)。
当使用 foreach
的枚举被中止时,枚举器将被丢弃。在 "early dispose" 的情况下,C# 迭代器方法执行所有活动的 finally 块。这意味着迭代器方法内的所有 using
语句都被接受,因为 using
基于 finally
.
为了使其更具体:Dispose
只能在 yield return
语句中的 C# 生成的枚举器上调用。只有 yield return
将控制权交给调用者。
生成的状态机跟踪在每个屈服点激活的 finally 块,并在 Dispose
方法中执行它们。
如果您简单地放弃一个枚举器 (File.ReadLines("file.txt").GetEnumerator();
),finally 块将不会被接受。没有机制可以做到这一点。
TL;DR:只要您处置最外层的枚举器和链中的所有枚举器(此处:Select
和 ReadLines
)正确处置它们的内部,文件在所有情况下都会被关闭使用 finally
.