You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
2.4 KiB

1 month ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace ShenTun.Ecg.Common
  8. {
  9. public class FileHelper
  10. {
  11. public static IEnumerable<string> GetAllMatchingPaths(string pattern)
  12. {
  13. char separator = Path.DirectorySeparatorChar;
  14. string[] parts = pattern.Split(separator);
  15. if (parts[0].Contains('*') || parts[0].Contains('?'))
  16. throw new ArgumentException("path root must not have a wildcard", nameof(parts));
  17. return GetAllMatchingPathsInternal(String.Join(separator.ToString(), parts.Skip(1)), parts[0]);
  18. }
  19. private static IEnumerable<string> GetAllMatchingPathsInternal(string pattern, string root)
  20. {
  21. char separator = Path.DirectorySeparatorChar;
  22. string[] parts = pattern.Split(separator);
  23. for (int i = 0; i < parts.Length; i++)
  24. {
  25. // if this part of the path is a wildcard that needs expanding
  26. if (parts[i].Contains('*') || parts[i].Contains('?'))
  27. {
  28. // create an absolute path up to the current wildcard and check if it exists
  29. var combined = root + separator + String.Join(separator.ToString(), parts.Take(i));
  30. if (!Directory.Exists(combined))
  31. return new string[0];
  32. if (i == parts.Length - 1) // if this is the end of the path (a file name)
  33. {
  34. return Directory.EnumerateFiles(combined, parts[i], SearchOption.TopDirectoryOnly);
  35. }
  36. else // if this is in the middle of the path (a directory name)
  37. {
  38. var directories = Directory.EnumerateDirectories(combined, parts[i], SearchOption.TopDirectoryOnly);
  39. var paths = directories.SelectMany(dir =>
  40. GetAllMatchingPathsInternal(String.Join(separator.ToString(), parts.Skip(i + 1)), dir));
  41. return paths;
  42. }
  43. }
  44. }
  45. // if pattern ends in an absolute path with no wildcards in the filename
  46. var absolute = root + separator + String.Join(separator.ToString(), parts);
  47. if (File.Exists(absolute))
  48. return new[] { absolute };
  49. return new string[0];
  50. }
  51. }
  52. }