FileSystemEnumerableIterator可以直接使用StrCmpLogicalW进行逻辑排序吗?

时间:2018-11-09 22:47:03

标签: c# ienumerable

从文件夹中检索文件列表时,是否可以直接使用StrCmpLogicalW Win32函数?我需要进行逻辑排序,将前导数字视为数字。

内置函数OrderBy<>OrderByDescending<>进行基于字符的排序。

在下面的代码中,我将集合复制到列表中,然后进行排序。它可以工作,但似乎是一个额外的步骤。//

/// <summary>
/// Descending logical sort for lists with numeric data
/// </summary>
public class StrCmpLogicalDescendingComparer : Comparer<string>
{
  [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
  private static extern int StrCmpLogicalW(string x, string y);

  public override int Compare(string x, string y)
  {
    // Provide elements in reverse order to sort descending
    return StrCmpLogicalW(y, x);
  }
}

/// <summary>
/// Examine folder and return the next file number in sequence
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
private int FindNextFileNumber(string folder)
{
  int result = -1;
  // Return an array of file names from the folder

  // Original attempt, does a character sort
  //var files = Directory.EnumerateFiles(folder)
  //              .OrderByDescending(filename => filename);

  var files = Directory.EnumerateFiles(folder);
  if (files.Count() > 0) {
    // Convert the collection to a list that can use the logical sorter
    List<string> sortableList = files.ToList();//= new List<string>();
    sortableList.Sort(new StrCmpLogicalDescendingComparer());
    foreach (string file in sortableList) {
      // Files with alpha will not qualify as a number, loop will
      // keep trying until it finds the highest number
      if (Int32.TryParse(Path.GetFileNameWithoutExtension(file), out result)) {
        result++;
        break;
      }
    }
  }
  // Check to see if there were any numeric files found
  if (result == -1) {
    result = 0;
  }
  return result;
}

1 个答案:

答案 0 :(得分:0)

现在,当您只对少数几个文件感兴趣时,您正在订购可能很大的文件列表,这似乎很浪费;想象一下成千上万的字母数字名称,以及少数几个数字名称...哎呀。为什么不先过滤掉不是数字的文件,然后再对其余的命令进行排序?

此方法的一个重要附带好处是,一旦您知道只有数字文件名,那么在不重复使用本机函数的情况下,正确地对它们进行排序很简单:

static int FindNextFileNumber(string folder)
{
    var i = 0;

    return Directory.EnumerateFiles(folder)
                    .Where(f => int.TryParse(f, out i))
                    .Select(f => i)
                    .OrderByDescending(n => n)
                    .FirstOrDefault();
}