c# - 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;
}
解决方案
现在,当您只对少数几个感兴趣时,您正在订购一个可能很大的文件列表,这似乎很浪费;想象成千上万个字母数字名称,而只有少数数字名称……哎呀。为什么不先过滤掉不是数字的文件,然后再订购其余的文件?
这种方法的一个重要的附带好处是,一旦您知道您只有数字文件名,那么在不重复使用本机函数的情况下正确排序它们是微不足道的:
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();
}
推荐阅读
- jquery - 当禁用连续循环并且滑块无法朝该方向移动时,如何在按钮上添加禁用类?
- r - slice_plot() 找不到函数错误
- autodesk-forge - 端点将 Autodesk 清单输出为 pdf 文件?
- c# - 如何在局部视图中使用界面
- angular - SSE Emitter over Spring MVC 并以角度调用它
- google-bigquery - Bigquery - 创建计划查询时出错:当目标数据集位于 JURISDICTION_EU 时,无法在 JURISDICTION_US 中创建传输
- javascript - 如何从 node.js 获取所有必需的模块作为单个文本文件或字符串?
- angular - Angular:如何调试控制未重定向到新路由的原因
- c# - 删除 ExpandoObject 中的属性
- c# - 给togglebutton一个默认文本wpf c#