使用LINQ计算C#中文件的数量

5

环境: C#,VStudio 2013,4.5框架,Winforms

目标:获取与存储在字符串数组中的扩展名匹配的文件夹和子文件夹中的文件数(计数)。扩展名数组可以带有“.”或不带。{" .dat",“txt”,“.msg”}

到目前为止我已经做了什么:当我在扩展名数组中使用"."时,一切正常:{".dat",".txt",".msg"}

我尝试了 Replace,但它总是返回0。

只有当数组中的所有字符串都带有“.”时,代码才有效:

string[] ext= new string[] { ".txt", ".msg", ".dat" };
totalFilesInTN = Directory.EnumerateFiles(dlg1.SelectedPath, "*.*", SearchOption.AllDirectories)
                          .Count(s => ext.Any(s1 => s1 == Path.GetExtension(s)));

不起作用的代码(始终返回0):

string[] ext= new string[] { "txt", ".msg", "dat" };
totalFilesInTN = Directory.EnumerateFiles(dlg1.SelectedPath, "*.*", SearchOption.AllDirectories)
                          .Count(s => ext.Any(s1 => s1 == Path.GetExtension(s).Replace(".", "")));

先尝试使用where子句,然后再进行计数。 - Nazmul
@Nazmul:基本上这与在Count中使用无Where但谓词相同。 - Tim Schmelter
我知道让我们尝试一下,看看有什么改变。有时 LINQ 无法做到这一点。 - Nazmul
4个回答

6

Path.GetExtension 方法的文档说明返回值为:

指定路径的扩展名(包括句点 "."),或 null,或 String.Empty。

你的第二个代码块去掉了 ".",所以没有一个元素会匹配。因此,你需要相反地列出文件扩展名列表,确保每个扩展名的开头都有一个 ".",然后使用第一个代码块。

string[] ext = new string[] {"txt", ".msg", ".dat" }
    .Select(x => x.StartsWith(".") ? x : "." + x)
    .ToArray();

1
using System.Linq 这个提示是多余的,因为 OP 已经在使用 LINQ 了,除此之外 +1。 - Tim Schmelter
好的观点。现在关于那些细节还为时过早 :) 但是我喜欢为未来的读者澄清事情。 - Steve Mitcham
我不想挑剔,但如果要被接受的话,也许值得注意一下为什么 OP 的第二种方法不起作用。因为它从 Path.GetExtension 的值中移除了点,但没有从他的数组扩展名中移除。 - Tim Schmelter

1
你需要替换数组ext元素和目录项中的.点。你需要使用s1的.Replace方法,将每个元素中的点删除后比较数组和文件扩展名。
string[] ext= new string[] { "txt", ".msg", "dat" };
totalFilesInTN = Directory.EnumerateFiles(dlg1.SelectedPath, "*.*", SearchOption.AllDirectories)
                 .Count(s => ext.Any(s1 => s1.Replace(".", "") == Path.GetExtension(s).Replace(".", "")));

1
由于您需要从两个扩展名中都删除点,所以它无法正常工作。 Path.GetExtension 始终会在扩展名前添加点。但是,您的扩展名数组可能包含没有点的扩展名。因此,如果要进行比较,则必须从两个扩展名中都删除点:

因此,不是

....Count(s => ext.Any(s1 => s1 == Path.GetExtension(s).Replace(".", "")));

这个:
....Count(s => ext.Any(s1 => si.Replace(".", "") == Path.GetExtension(s).Replace(".", "")));

但是正如其他人提到的那样,修复无效源码,修改数组,使其只包含带点的扩展名。这样它会更加易读和高效。
您还可以使用Contains:
....Count(s => ext.Contains(Path.GetExtension(s)));

0

GetExtension()方法总是包含“.”,因此您需要对要检查的扩展名进行规范化。

string[] extensions = new string[] { "docx", ".msg", "pdf" };
var filesCount = Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories)
 .Count(filePath => extensions.Any(e => (e.StartsWith(".") ? e : "." + e) == Path.GetExtension(filePath)));

但最好的做法是在开始时只对集合进行一次规范化处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接