【发布时间】:2019-05-26 01:20:08
【问题描述】:
我在一个文件夹中有一堆文本文件,它们都应该有相同的标题。换句话说,所有文件的前 100 行应该是相同的。所以我写了一个函数来检查这个条件:
private static bool CheckHeaders(string folderPath, int headersCount)
{
var enumerators = Directory.EnumerateFiles(folderPath)
.Select(f => File.ReadLines(f).GetEnumerator())
.ToArray();
//using (enumerators)
//{
for (int i = 0; i < headersCount; i++)
{
foreach (var e in enumerators)
{
if (!e.MoveNext()) return false;
}
var values = enumerators.Select(e => e.Current);
if (values.Distinct().Count() > 1) return false;
}
return true;
//}
}
我使用枚举器的原因是内存效率。我不是将所有文件内容加载到内存中,而是逐行同时枚举文件,直到发现不匹配,或者检查了所有标题。
注释的代码行很明显我的问题。我想使用using 块来安全地处理所有枚举器,但不幸的是using (enumerators) 无法编译。显然using 只能处理一个一次性对象。我知道我可以手动处理枚举数,方法是将整个事物包装在 try-finally 块中,并最终在内部循环中运行处理逻辑,但这似乎很尴尬。在这种情况下,我是否可以采用任何机制使 using 语句成为可行的选择?
更新
我刚刚意识到我的函数有一个严重的缺陷。枚举器的构造并不稳健。锁定的文件可能会导致异常,而一些枚举器已经创建。这些枚举器将不会被释放。这是我想要解决的问题。我正在考虑这样的事情:
var enumerators = Directory.EnumerateFiles(folderPath)
.ToDisposables(f => File.ReadLines(f).GetEnumerator());
扩展方法ToDisposables 应确保在发生异常时不会留下任何一次性物品。
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
-
“锁定的文件会导致异常”中的“locked”是什么意思?
-
@Alex 我的意思是锁定阅读。例如,当我尝试从我的应用程序打开它时,已经从另一个应用程序打开带有标志
FileShare.None的文件将导致异常。 -
我明白了。
var enumerators = Directory.EnumerateFiles(folderPath).Select(f => { try { return File.ReadLines(f).GetEnumerator(); } catch { return null; } }).Where(f => f != null).ToArray();帮助我以这种方式锁定文件。 -
@Alex 在这种情况下,您将有一个被吞没的异常和一个空枚举器。在我的情况下,我想被告知一个文件被锁定,以便我可以解锁它并再次调用我的函数。对某些文件的标题进行部分检查对我没有用。
标签: c# .net dispose enumeration