1 /// <summary>
2 /// 根据通配符和搜索条件计算给定目录中的文件字节长度
3 /// </summary>
4 /// <param name="path"> 要搜索的目录的相对或绝对路径。 此字符串不区分大小写。</param>
5 /// <param name="searchPatter">要与 path 中的文件名匹配的搜索字符串。 此参数可以包含有效的文本路径和通配符(* 和 ?) 字符(参见“备注”)的组合,但不支持正则表达式。</param>
6 /// <param name="searchOption">指定搜索操作是应仅包含当前目录还是应包含所有子目录的枚举值之一。 默认值为 System.IO.SearchOption.TopDirectoryOnly。</param>
7 /// <returns></returns>
8 private static Int64 DirectoryBytes(string path, string searchPatter, SearchOption searchOption)
9 {
10 Int64 masterTotal = 0;
11
12 //返回一个可枚举集合,它包含 path 指定的目录中与指定的搜索模式和选项匹配的文件的完整名称(包括路径)。
13 var files = Directory.EnumerateFiles(path, searchPatter, searchOption);
14
15 //提供有关执行的完成状态 System.Threading.Tasks.Parallel 循环。
16 ParallelLoopResult parallelLoopResult = Parallel.ForEach<string, Int64>(
17 //source 可枚举的数据源
18 files,
19
20 //localInit 用于返回每个任务的本地数据的初始状态的函数委托。
21 //每个任务开始前调用一次
22 () =>
23 {
24 //开始前总计数初始化为0,即将taskLocalTotal初始化为0
25 return 0;
26 },
27
28 //body 将为每个迭代调用一次的委托。
29 (file, loopState, index, taskLocalTotal) =>
30 {
31 //获得这个文件的大小,把它添加到这个任务的累加值上
32 Int64 fileLength = 0;
33 FileStream fileStream = null;
34 try
35 {
36 fileStream = File.OpenRead(file);
37 fileLength = fileStream.Length;
38 }
39 catch (IOException)
40 {
41 //忽略拒绝访问的任何文件
42 }
43 finally
44 {
45 fileStream?.Dispose();
46 }
47 return taskLocalTotal + fileLength;
48 },
49
50 //localFinally 用于对每个任务的本地状态执行一个最终操作的委托。
51 taskLocalTotal =>
52 {
53 //将这个任务的总计值(taskLocalTotal)加到总的总计值(masterTotal)上
54 Interlocked.Add(ref masterTotal, taskLocalTotal);
55 }
56 );
57
58 return masterTotal;
59 }