如何解决File.ReadLines(filePath).First() 是否立即关闭文件? 安全
我知道在 IEnumerable
循环中使用 File.ReadLines()
返回的 foreach
时,文件会在循环后自动关闭。
我只需要快速检查文件的第一行。这足够了吗,还是会保持文件打开?
protected void Append(string filePath,Encoding encoding)
{
try
{
string firstLine = File.ReadLines(filePath,encoding).First();
// more code here
}
catch
{
// more code here
}
}
解决方法
(请注意,这是针对返回 File.ReadLines()
的 IEnumerable<String>
- 这不适用于返回 File.ReadAllLines()
的 String[]
。)
File.ReadLines(filePath).First()
是否立即关闭文件?
是的
...假设“立即”是指当整个语句完成时 - 而不仅仅是内部的 ReadLines()
子表达式。
- 在内部,
File.ReadLines()
返回一个 instance ofReadLinesIterator
- 这是一个IEnumerable<T>
。 - 当
IEnumerable<T>
被迭代时,C#/.NET 使用IEnumerable<T>.GetEnumerator<T>()
返回一个IEnumerator<T>
,它必须在程序完成迭代后被处理它想要什么。- 因为
IEnumerator<T>
实例必须被处理,所以我们总是鼓励您使用foreach
为您处理此问题(而不是自己手动处理IEnumerator<T>
) .-
foreach
还将确保IEnumerator<T>
在foreach
循环体内抛出异常时被释放。
-
- 因为
- 在此特定情况下,
ReadLinesIterator
包含一个StreamReader
(其中包含打开的FileStream
)。当ReadLinesIterator
被释放时,内部StreamReader
关闭,进而关闭FileStream
。 -
.Frist()
方法是 Linq 的Enumerable.First( IEnumerable<T> source )
。- 在内部,Linq 的
First()
与调用foreach( T item in source )
并立即在 foreach 内部返回相同 - 因此First
方法将为您处理ReadLinesIterator
。
- 在内部,Linq 的
安全
我注意到 ReadLinesIterator
is both an IEnumerator<T>
and an IEnumerable<T>
并且它包装了一个开放的 StreamReader
- 这确实意味着您在使用 ReadLines()
时需要小心以确保 {{ 1}} 你看到的实际上是迭代的,否则你有泄漏打开文件句柄的风险。
...这也意味着,如果您使用的是 Linq 方法链并且在 Linq 链内部但在外部发生异常,则任何 Linq 的内部 IEnumerable<T>
/{{1} }/try/catch
块,那么您将泄漏一个文件句柄,该句柄在 GC 完成 foreach
之前不会关闭......尽管我承认我很难想到什么时候会发生这种情况。
File.ReadLines
返回 IEnumerable<string>
。 Enumerable 使用 IEnumerator<string>
读取行,这是一次性的。
阅读第一行并确保资源安全的正确方法:
var lines = File.ReadLines(path);
string firstLine;
using (var it = lines.GetEnumerator())
{
if (!it.MoveNext())
throw new InvalidOperationException("File is empty");
firstLine = it.Current;
}
UseLine(firstLine);
虽然复杂,但绝对安全
,使用流阅读器读取文件的最佳实践 ID。
var lines = new List<string>();
using (StreamReader reader = new StreamReader(@"C:\test.txt")) {
var line = reader.ReadLine();
while (line != null) {
lines.Add(line);
line = reader.ReadLine();
}
}
一旦代码移出 using 语句,填充对象将被释放,wfile 将被关闭。 File.ReadLines 从不关闭文件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。