【问题标题】:"Illegal characters in path" error using wildcards with Directory.GetFiles“路径中的非法字符”错误在 Directory.GetFiles 中使用通配符
【发布时间】:2017-07-20 18:03:59
【问题描述】:

我有一个包含多个子目录的目录,其中包含 .doc 文件。示例:

C:\Users\user\Documents\testenviroment\Released\test0.doc
C:\Users\user\Documents\testenviroment\Debug\test1.doc
C:\Users\user\Documents1\testenviroment\Debug\test2.doc
C:\Users\user\Documents1\testenviroment\Released\test20.doc

我想获取所有 Debug 文件夹下的所有 test*.doc 文件。我试过了:

string[] files = Directory.GetFiles(@"C:\Users\user", "*Debug\\test*.doc",
    SearchOption.AllDirectories);

它给了我一个“路径中的非法字符”错误。

如果我尝试:

string[] files = Directory.GetFiles(@"C:\Users\user", "\\Debug\\test*.doc",
    SearchOption.AllDirectories); 

我收到另一个错误:“找不到路径 C:\Users\user\Debug 的一部分”。

【问题讨论】:

  • 如果路径类似于C:\Users\user\Documents,为什么要在C:\Users\user\Debug 中搜索?
  • @HimBromBeere:是的,你可以。会计。到 MSDN The search string to match against the names of files in path. This parameter can contain a combination of valid literal path and wildcard (* and ?) characters (see Remarks), but doesn't support regular expressions. msdn.microsoft.com/en-us/library/ms143316(v=vs.110).aspx
  • 你的路径中肯定有非法字符。您的搜索字符串没有任何问题/
  • 我的错。是的,实际上看起来不够好。通配符是正确的,这就是使问题一见钟情的原因。

标签: c#


【解决方案1】:

第二个参数,搜索模式,仅适用于文件名。所以你需要迭代你想要搜索的目录,然后在每个目录上调用Directory.GetFiles(directory, "test*.doc")

如何编写该代码取决于您希望它有多健壮以及您想要做出什么假设(例如 “所有 Debug 目录总是在用户目录中的两个级别” "Debug 目录可以在任何级别进入用户目录").

How to recursively list all the files in a directory in C#?

或者,如果您想搜索所有子目录,然后丢弃不符合您偏好的文件,请参阅Searching for file in directories recursively

var files = Directory.GetFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
               .Where(f => f.IndexOf(@"\debug", StringComparison.OrdinalIgnoreCase) >= 0);

但请注意,这可能不利于性能,因为它会扫描不相关的目录。

【讨论】:

    【解决方案2】:

    您在搜索模式中包含了一个意外的文件夹。根据docs

    searchPattern 类型:System.String 要匹配的搜索字符串 路径中的文件名。该参数可以包含一个组合 有效的文字路径和通配符(* 和?)字符(见备注), 但不支持正则表达式。

    考虑到这一点,尝试这样的事情:

    String[] files = Directory.GetFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
                     .Where(file => file.Contains("\\Debug\\"))
                     .ToArray();
    

    这将获取您指定目录中的所有文件并返回路径中带有Debug 的文件。考虑到这一点,请尽量缩小搜索目录的范围。

    注意:

    我的原始答案包括EnumerateFiles,它会像这样工作(确保通过search option(感谢@CodeCaster)):

    String[] files = Directory.EnumerateFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
                     .Where(file => file.Contains("\\Debug\\"))
                     .ToArray();
    

    我刚刚运行了一个测试,第二个似乎较慢,但在较大的文件夹上可能会更快。值得牢记。

    编辑:来自@pinkfloydx33的注释

    实际上,我实际上已经拆除了我拥有的系统 遗传。尝试返回数组和 也杀死内存占用。问题被转移了转换 交给无数的同行

    因此,对于较大的目录,使用第二个选项会更安全。

    【讨论】:

    • 可能更好地使用 DirectoryInfo.EnumerateFiles 来利用返回值的可枚举性。否则,所有结果都会提前返回,这可能会导致包含大量文件的目录出现问题
    • @pinkfloydx33 在您评论时添加了一个示例:)
    • 我实际上已经把我继承的系统拆掉了。尝试返回数组并杀死内存占用也花费了很多时间。问题被转移到可枚举的对应物上。
    • @pinkfloydx33 谢谢,很高兴知道。我已将该评论添加到答案中,以便人们清楚使用哪个选项。
    • 虽然文件夹中的文件数量比您对“典型”文件夹的预期大几个数量级。当你像你一样添加 Where 扩展方法时,切换到 enumerable 也会有好处,并且应该防止两次迭代文件(一次获取,第二次获取位置)
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 2018-03-01
    • 2019-08-30
    • 1970-01-01
    相关资源
    最近更新 更多