File.ReadLines(filePath).First() 是否立即关闭文件?
Does File.ReadLines(filePath).First() close the file immediately?
我知道在 foreach
循环中使用 File.ReadLines()
返回的 IEnumerable
时,文件会在循环后自动关闭。
我只需要快速检查文件的第一行。这足够了还是会保持文件打开?
protected void Append(string filePath, Encoding encoding)
{
try
{
string firstLine = File.ReadLines(filePath, encoding).First();
// more code here
}
catch
{
// more code here
}
}
(请注意,这是针对 File.ReadLines()
其中 returns 和 IEnumerable<String>
- 这不适用于 File.ReadAllLines()
其中 returns String[]
.)
Does File.ReadLines(filePath).First()
close the file immediately?
是
...假设“立即”是指 整个语句 完成时 - 而不仅仅是内部 ReadLines()
子表达式。
- 在内部,
File.ReadLines()
returns 一个 instance of ReadLinesIterator
- 这是一个 IEnumerable<T>
.
- 当迭代
IEnumerable<T>
时,C#/.NET 使用 IEnumerable<T>.GetEnumerator<T>()
其中 returns 和 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
.
安全
我注意到 ReadLinesIterator
is both an IEnumerator<T>
and an IEnumerable<T>
并且它包装了一个开放的 StreamReader
- 这意味着您在使用 ReadLines()
时确实需要小心以确保IEnumerable<T>
你看到的实际上是迭代过的,否则你确实有泄漏打开文件句柄的风险。
...这也意味着,如果您正在使用 Linq 方法链,并且异常发生在 Linq 链内部 但在外部 Linq 的任何内部 try/catch
/foreach
/using
块然后你将泄漏一个文件句柄,该文件句柄在 GC 完成 ReadLinesIterator
之前不会关闭......尽管我承认我很难想到什么时候可以发生了。
File.ReadLines
returnsIEnumerable<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);
这很复杂,但肯定是安全的
使用流 reader.
读取文件的最佳实践 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 语句,fill 对象将被释放,wfile 将被关闭。 File.ReadLines 从不关闭文件。
我知道在 foreach
循环中使用 File.ReadLines()
返回的 IEnumerable
时,文件会在循环后自动关闭。
我只需要快速检查文件的第一行。这足够了还是会保持文件打开?
protected void Append(string filePath, Encoding encoding)
{
try
{
string firstLine = File.ReadLines(filePath, encoding).First();
// more code here
}
catch
{
// more code here
}
}
(请注意,这是针对 File.ReadLines()
其中 returns 和 IEnumerable<String>
- 这不适用于 File.ReadAllLines()
其中 returns String[]
.)
Does
File.ReadLines(filePath).First()
close the file immediately?
是
...假设“立即”是指 整个语句 完成时 - 而不仅仅是内部 ReadLines()
子表达式。
- 在内部,
File.ReadLines()
returns 一个 instance ofReadLinesIterator
- 这是一个IEnumerable<T>
. - 当迭代
IEnumerable<T>
时,C#/.NET 使用IEnumerable<T>.GetEnumerator<T>()
其中 returns 和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()
时确实需要小心以确保IEnumerable<T>
你看到的实际上是迭代过的,否则你确实有泄漏打开文件句柄的风险。
...这也意味着,如果您正在使用 Linq 方法链,并且异常发生在 Linq 链内部 但在外部 Linq 的任何内部 try/catch
/foreach
/using
块然后你将泄漏一个文件句柄,该文件句柄在 GC 完成 ReadLinesIterator
之前不会关闭......尽管我承认我很难想到什么时候可以发生了。
File.ReadLines
returnsIEnumerable<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);
这很复杂,但肯定是安全的
使用流 reader.
读取文件的最佳实践 IDvar 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 语句,fill 对象将被释放,wfile 将被关闭。 File.ReadLines 从不关闭文件。