首页 > 解决方案 > FileSystemEnumerableIterator 可以直接使用 StrCmpLogicalW 进行逻辑排序吗?

问题描述

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;
}

标签: c#ienumerable

解决方案


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

这种方法的一个重要的附带好处是,一旦您知道您只有数字文件名,那么在不重复使用本机函数的情况下正确排序它们是微不足道的:

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();
}

推荐阅读