using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
namespace FileSortInfo
{
public class DirectoryFiles
{
/// <summary>
/// 获取目录下的文件,并按名称从小到大进行排序(支持字符串数字混合型)
/// </summary>
/// <param name="Dir"></param>
/// <param name="reverse">反向,从大到小</param>
/// <returns></returns>
public static List<string> GetFiles(string Dir, bool reverse = false)
{
FileInfo[] infos = new DirectoryInfo(Dir).GetFiles();
SortName[] sortNames = new SortName[infos.Length];
for(int i=0; i<infos.Length; i++)
{
sortNames[i] = new SortName(infos[i]);
}
string txt1 = @"D:\tmp\test\1.txt";
foreach(var iteam in sortNames) { File.AppendAllText(txt1, "\r\n" + iteam.appendInfo as string); }
// 名称排序
Array.Sort(sortNames, (name1, name2) =>
{
if (reverse)
{
if (name1 == name2) return 0;
else if (name1 > name2) return -1;
else return 0;
}
else
{
if (name1 == name2) return 0;
else if (name1 > name2) return 1;
else return -1;
}
});
string txt2 = @"D:\tmp\test\2.txt";
foreach (var iteam in sortNames) { File.AppendAllText(txt2, "\r\n" + iteam.appendInfo as string); }
var list = sortNames.Select(x => x.appendInfo as string).ToList();
return list;
}
/// <summary>
/// 获取目录下的文件,并按名称从小到大进行排序
/// </summary>
/// <param name="Dir"></param>
/// <param name="reverse">反向,从大到小</param>
/// <returns></returns>
public static List<string> GetFiles0(string Dir, bool reverse = false)
{
FileInfo[] infos = new DirectoryInfo(Dir).GetFiles();
SortName[] sortNames = new SortName[infos.Length];
for (int i = 0; i < infos.Length; i++)
{
sortNames[i] = new SortName(infos[i]);
}
string txt1 = @"D:\tmp\test\1.txt";
foreach (var iteam in sortNames) { File.AppendAllText(txt1, "\r\n" + iteam.appendInfo as string); }
// 按SortName进行排序
SortName tmp;
for (int i = 0; i < sortNames.Length - 1; i++)
{
for (int j = i + 1; j < sortNames.Length; j++)
{
if (reverse)
{
if (sortNames[i] < sortNames[j])
{
tmp = sortNames[i];
sortNames[i] = sortNames[j];
sortNames[j] = tmp;
}
}
else
{
if (sortNames[i] > sortNames[j])
{
tmp = sortNames[i];
sortNames[i] = sortNames[j];
sortNames[j] = tmp;
}
}
}
}
string txt2 = @"D:\tmp\test\2.txt";
foreach (var iteam in sortNames) { File.AppendAllText(txt2, "\r\n" + iteam.appendInfo as string); }
List<string> list = new List<string>();
foreach (var name in sortNames)
{
list.Add(name.appendInfo as string);
}
return list;
}
}
/// <summary>
/// 定义SortName对数字和非数字混合的字符串,进行排序(数字部分按数字顺序、非数字部分按字符串顺序)
/// </summary>
public class SortName
{
List<SortNum> sortNums = new List<SortNum>(); // 记录用于排序,的排序数SortNum
string nameStr = ""; // 记录排序原始字符串
public object appendInfo = null;
/// <summary>
/// 定义SortName对数字和非数字混合的字符串,进行排序(数字部分按数字顺序、非数字部分按字符串顺序)
/// </summary>
/// <param name="Name"></param>
public SortName(string Name, object appendInfo = null)
{
this.nameStr = Name;
this.appendInfo = appendInfo;
InitSortNums(Name);
}
/// <summary>
/// 从FileInfo构建SortName
/// </summary>
/// <param name="fileInfo"></param>
public SortName(FileInfo fileInfo)
{
this.nameStr = Path.GetExtension(fileInfo.Name) + Path.GetFileNameWithoutExtension(fileInfo.Name);
this.appendInfo = fileInfo.FullName;
InitSortNums(nameStr); // 以文件名为排序依据
}
public String ToString()
{
return nameStr;
}
/// <summary>
/// 初始化排序值信息
/// </summary>
/// <param name="Name"></param>
private void InitSortNums(string Name)
{
bool charIsNum = false;
List<char> Tmp = new List<char>();
for (int i = 0; i < Name.Length; i++)
{
char c = Name[i];
if (isNum(c)) // 当前字符,是数字字符
{
if(!charIsNum) // Tmp中之前存储的字符,不是数字字符
{
charIsNum = true;
if(Tmp.Count > 0) RecordSortNum(Tmp, false);
}
Tmp.Add(c);
}
else
{ // 当前字符,非数字字符
if (charIsNum) // Tmp中之前存储的字符,是数字字符
{
charIsNum = false;
if (Tmp.Count > 0) RecordSortNum(Tmp, true);
}
Tmp.Add(c);
}
}
if (Tmp.Count > 0) RecordSortNum(Tmp, charIsNum); // 剩余字符转化为SortNum,并记录
}
/// <summary>
/// 记录单个SortNum项
/// </summary>
/// <param name="Tmp"></param>
/// <param name="isNum"></param>
private void RecordSortNum(List<char> Tmp, bool isNum)
{
if (Tmp.Count > 0)
{
SortNum Num = new SortNum(new string(Tmp.ToArray()), isNum);
sortNums.Add(Num);
Tmp.Clear();
}
}
/// <summary>
/// 判断c是否为数字
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
private bool isNum(char c)
{
return ('0' <= c && c <= '9');
}
/// <summary>
/// 判断name1 是否大于 name2
/// </summary>
/// <param name="name1"></param>
/// <param name="name2"></param>
/// <returns></returns>
public static bool operator >(SortName name1, SortName name2)
{
return Compare(name1, name2) > 0;
}
/// <summary>
/// 判断name1 是否小于 name2
/// </summary>
/// <param name="name1"></param>
/// <param name="name2"></param>
/// <returns></returns>
public static bool operator <(SortName name1, SortName name2)
{
return Compare(name1, name2) < 0;
}
/// <summary>
/// 判断name1 是否等于 name2
/// </summary>
/// <param name="name1"></param>
/// <param name="name2"></param>
/// <returns></returns>
public static bool operator ==(SortName name1, SortName name2)
{
return Compare(name1, name2) == 0;
}
/// <summary>
/// 判断name1 是否不等于 name2
/// </summary>
/// <param name="name1"></param>
/// <param name="name2"></param>
/// <returns></returns>
public static bool operator !=(SortName name1, SortName name2)
{
return Compare(name1, name2) != 0;
}
/// <summary>
/// 对SortNum进行比对
/// </summary>
/// <param name="name1"></param>
/// <param name="name2"></param>
/// <returns></returns>
public static int Compare(SortName name1, SortName name2)
{
if (name1.nameStr.Equals(name2.nameStr)) return 0;
else
{
// 共有字符段部分
int minLen = Math.Min(name1.sortNums.Count, name2.sortNums.Count);
for (int i = 0; i < minLen; i++)
{
SortNum sNum1 = name1.sortNums[i];
SortNum sNum2 = name2.sortNums[i];
if (sNum1 > sNum2) return 1;
else if (sNum1 < sNum2) return -1;
}
// 剩余字符段部分
if (name1.sortNums.Count == name2.sortNums.Count) return 0;
else if (name1.sortNums.Count > name2.sortNums.Count) return 1; // 更多的字符,靠后
else return -1;
}
}
}
/// <summary>
/// 记录单个数字或字符串,并进行对比
/// </summary>
public class SortNum
{
bool isNum = false;
string NumStr = "";
long NumLong = 0;
public SortNum(string NumStr, bool isNum)
{
this.NumStr = NumStr;
this.isNum = isNum;
if(isNum) NumLong = long.Parse(NumStr);
}
public String ToString()
{
return NumStr;
}
/// <summary>
/// 判断num1 > num2
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static bool operator >(SortNum num1, SortNum num2)
{
return Compare(num1, num2) > 0;
}
/// <summary>
/// 判断num1 < num2
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static bool operator <(SortNum num1, SortNum num2)
{
return Compare(num1, num2) < 0;
}
/// <summary>
/// 判断num1 == num2
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static bool operator ==(SortNum num1, SortNum num2)
{
return Compare(num1, num2) == 0;
}
/// <summary>
/// 判断num1 != num2
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static bool operator !=(SortNum num1, SortNum num2)
{
return Compare(num1, num2) != 0;
}
/// <summary>
/// 对SortNum进行比对
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static int Compare(SortNum num1, SortNum num2)
{
if (num1.NumStr.Equals(num2.NumStr)) return 0; // 字符串完全相同,则相同
else if (num1.isNum && num2.isNum) // 都是数字字符串
{
if (num1.NumLong > num2.NumLong) return 1; // 数值比对较大
else if (num1.NumLong < num2.NumLong) return -1; // 较小
else
{
return Compare(num1.NumStr, num2.NumStr); // 数值比对相同,继续按字符串比对
}
}
else if (num1.isNum) return 1; // 是数字字符串,则排在普通字符串之前
else if (num2.isNum) return -1;
else return Compare(num1.NumStr, num2.NumStr); // 都是字符串按字符串比对
}
/// <summary>
/// 逐个字符比对两个字符串的大小
/// </summary>
/// <param name="Str1"></param>
/// <param name="Str2"></param>
/// <returns></returns>
public static int Compare(string Str1, string Str2)
{
int minLength = Math.Min(Str1.Length, Str2.Length);
for (int i = 0; i < minLength; i++)
{
char c1 = Str1[i];
char c2 = Str2[i];
if (c1 > c2) return 1;
else if (c1 < c2) return -1;
}
if (Str1.Length == Str2.Length) return 0;
else if (Str1.Length > Str2.Length) return 1;
else return -1;
}
}
}