It's unclear what is the desired result looks like. If you want to sort files by their last write time a
simple Linq query will do:
var arrFi = new DirectoryInfo(source_path)
.EnumerateFiles("*.*")
.OrderBy(file => file.LastWriteTime)
.ToArray();
If you want to order files by their names in natural order (i.e. "1" < "5" < "9" < "10" < "12" < "100"
) the
query itself will be as easy as the previous one:
var arrFi = new DirectoryInfo(source_path)
.EnumerateFiles("*.*")
.OrderBy(file => file.Name, new StringNaturalComparer(null))
.ToArray();
But you have to implement the comparer:
public sealed class StringNaturalComparer : IComparer<String> {
private readonly IComparer<string> m_Comparer;
private static List<string> ToChunks(string value) {
List<string> result = new();
StringBuilder sb = null;
bool isDigit = false;
foreach (var c in value) {
if (sb is null) {
sb = new StringBuilder(value.Length);
isDigit = char.IsDigit(c);
sb.Append(c);
}
else if (isDigit != char.IsDigit(c)) {
result.Add(sb.ToString());
sb.Clear();
isDigit = char.IsDigit(c);
}
sb.Append(c);
}
if (sb != null)
result.Add(sb.ToString());
return result;
}
public StringNaturalComparer(IComparer<string> comparer) {
m_Comparer = comparer == null ? StringComparer.Ordinal : comparer;
}
public int Compare(string left, string right) {
if (ReferenceEquals(left, right))
return 0;
else if (left == null)
return -1;
else if (right == null)
return 1;
var lefts = ToChunks(left);
var rights = ToChunks(right);
int result;
for (int i = 0; i < Math.Min(lefts.Count, rights.Count); ++i) {
string leftChunk = lefts[i];
string rightChunk = rights[i];
if (char.IsDigit(leftChunk[0]) && char.IsDigit(rightChunk[0])) {
result = leftChunk.Length.CompareTo(rightChunk.Length);
if (result != 0)
return result;
}
result = m_Comparer.Compare(leftChunk, rightChunk);
if (result != 0)
return result;
}
return lefts.Count.CompareTo(rights.Count);
}
}