【问题标题】:Doc and docx filetypes returns the same fileDoc 和 docx 文件类型返回相同的文件
【发布时间】:2017-06-21 21:32:30
【问题描述】:

我正在尝试获取下面提到的路径中的文档文件。所以我将文件类型设置为 doc 和 docx。

在文档文件夹中,我有文件“issues.docx”

 string path1 = "C:\\Documents\\";
 var dir =  new DirectoryInfo(path1);
 string[] fileTypes = { "doc", "docx" };       
 var myFiles = fileTypes.SelectMany(dir.GetFiles);

这是我在我的应用程序中使用的代码。在这里它会返回两次 issues.docx 文件。但它应该只返回一次文件。如何在不更改fileTypes 的情况下实现它?

【问题讨论】:

  • *.doc 也将匹配 *.docx(用于旧版 8.3 命名支持)。 Better to use EnumerateFiles()
  • EnumerateFiles() 也返回相同的结果
  • @Joy NTFS 不是搜索引擎。执行两个单独的搜索将导致对所有文件进行两次扫描,从而使时间加倍。如果您使用EnumerateFiles 搜索*.doc* 文件并随后按扩展名拆分它们会更快,例如使用ToDictionary
  • 我在一个目录中创建了A.DOC 和A.DOCX,您的代码重复,因为它遍历两次 并且通配符冲突,Directory.EnumerateFiles("c:\\null\\temp", "*.*").Where(s => s.EndsWith(".doc") || s.EndsWith(".docx")); 只返回每个文件一次。
  • @Joy 您是否按照链接的答案显示的内容进行操作,或者您是否使用了与 EnumerateFiles 相同的错误代码?链接的问题读取匹配的文件一次然后过滤它们

标签: c#


【解决方案1】:

NTFS 不是搜索引擎。执行两个单独的搜索将导致对所有文件进行两次扫描,花费双倍的时间。

如果您使用 EnumerateFiles 搜索 .doc 文件并随后按扩展名拆分它们会更快,例如使用 ToDictionary。

var filesByExtension=dir.EnumerateFiles("*.doc?")
                        .ToDictionary(fi=>fi.Extension,fi=>fi);

如果需要,您还可以对结果进行分组,例如计算统计数据:

dir.EnumerateFiles("*.doc?")
   .GroupBy(fi=>fi.Extension)
   .Select(g=>new {
                      Extension=g.Key,
                      TotalSize=g.Sum(f=>f.Length), 
                      Files=g.ToArray()
           });

如果您想要加速搜索,您可以使用 Windows Search 服务。但是,调用它并不简单,您必须将其称为OLEDB database。如果索引器仍在扫描文件,结果也可能不准确

更新

如果要搜索的文件类型没有共同点,可以在Where表达式中进行过滤:

var extensions=new[]{".doc",".docx",".png",".jpg"};
dir.EnumerateFiles()
   .Where(fi=>extensions.Contains(fi.Extension))
   .GroupBy(fi=>fi.Extension)
   .Select(g=>new {
                      Extension=g.Key,
                      TotalSize=g.Sum(f=>f.Length), 
                      Files=g.ToArray()
           });

Where 可用于过滤掉小文件或大文件,例如:

var extensions=new[]{".doc",".docx",".png",".jpg"};
dir.EnumerateFiles()
   .Where(fi=>extensions.Contains(fi.Extension) && fi.Length>1024)
   .GroupBy(fi=>fi.Extension)
   .Select(g=>new {
                      Extension=g.Key,
                      TotalSize=g.Sum(f=>f.Length), 
                      Files=g.ToArray()
           });

【讨论】:

  • 在我的文件类型中,我会得到任何文件类型,如 png、jpg、pdf 等。那么如何将其更改为通用解决方案?
  • 如果您不想按特定类型进行过滤,请不要使用模式。不过,您询问了 doc 和 docx 文件 - 您的代码对 doc 和 docx 进行了两次单独调用。无论如何,它仍然是一个完整的扫描。如果要进一步过滤结果,请添加Where 子句
  • 此解决方案还会两次返回文件。 .
  • @Joy 不,它没有。 EnumerateFiles 只运行一次。除非您确实有两个同名的文件,例如在不同的目录中。或者你有一个.doc 和一个.docx 文件
  • @Joy 这是一个基本概念,您必须发布一个完全可重现的示例。尝试读取仅因扩展名不同的文件not 会导致重复。 File1.doc 是与 File1.docx 不同的文件。如果您要求两个扩展名,两者都会出现在结果中。
猜你喜欢
  • 2012-01-15
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 2016-03-03
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
相关资源
最近更新 更多