解決在我的文章的底部。IComparer問題+如何在.NET中自然地排序字符串數組(FILE_10> FILE_2)?
或者更具體地說:
我有一大堆的FileInfo對象(我需要的FileInfo對象排除隱藏,系統和重新分析點文件)。
我需要的FileInfo []自然根據他們FileInfo.FullName進行排序。所以FILE_10.ext應該在FILE_2.ext之後。幸運的是,FileInfo []僅包含一個擴展名的文件。
我實現了一個比較器:
/// <summary>
/// Compares FileInfo objects based on the files full path.
/// This comparer is flawed in that it will only work correctly
/// on files with the same extension.
/// Though that could easily be fixed.
/// </summary>
private class FileInfoSorter : IComparer
{
int IComparer.Compare(Object x, Object y)
{
FileInfo _x = x as FileInfo;
FileInfo _y = y as FileInfo;
// FYI:
//ExprFileVersion = new Regex("(.*)_([0-9]+)\\.[^\\.]+$", RegexOptions.Compiled);
Match m1 = RegExps.ExprFileVersion.Match(_x.FullName);
Match m2 = RegExps.ExprFileVersion.Match(_y.FullName);
if (m1.Success && m2.Success) // we have versioned files
{
int n1;
int n2;
try
{
n1 = int.Parse(m1.Groups[2].Value);
}
catch (OverflowException ex)
{
// Don't know if this works.
ex.Data["File"] = _x.FullName;
throw;
}
try
{
n2 = int.Parse(m2.Groups[2].Value);
}
catch (OverflowException ex)
{
// Don't know if this works.
ex.Data["File"] = _y.FullName;
throw;
}
string s1 = m1.Groups[1].Value;
string s2 = m2.Groups[1].Value;
if (s1.Equals(s2))
{
return n1.CompareTo(n2); // compare numbers naturally. E.g. 11 > 6
}
else // not the same base file name. So the version does not matter.
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
else // not versioned
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
}
現在出現的問題是int.Parse拋出一個OverflowException異常,我沒能趕上在正確的點(它再次出現在return語句的行某種原因,我無法進一步智能處理它,因爲它永遠不會到達那裏)。
的問題是:是否有這樣的事情實現的預比較器?這個例外在有趣的地方出現的原因是什麼?
調用代碼:
IComparer fiComparer = new FileInfoSorter();
try
{
Array.Sort(filesOfExtInfo, fiComparer);
}
catch (OverflowException ex)
{
// Do not know yet if I can use ex.Data in this way.
WriteStatusLineAsync("Error: Encountered too large a version number on file: " + ex.Data["File"]);
}
EDIT1:Int.Parse拋出OverflowException異常,當它遇到太大的數目。它不應該定期發生,但我希望它覆蓋。
編輯2:我最終調整了我自己的比較器。從int.Parse中取出,並用零填充以便進行比較。 代碼在這裏:
public class FileInfoSorter : IComparer
{
int IComparer.Compare(Object x, Object y)
{
FileInfo _x = x as FileInfo;
FileInfo _y = y as FileInfo;
Match m1 = RegExps.ExprFileVersion.Match(_x.FullName);
Match m2 = RegExps.ExprFileVersion.Match(_y.FullName);
if (m1.Success && m2.Success) // we have versioned files
{
string n1;
string n2;
n1 = m1.Groups[2].Value;
n2 = m2.Groups[2].Value;
string s1 = m1.Groups[1].Value;
string s2 = m2.Groups[1].Value;
int max = Math.Max(n1.Length, n2.Length);
n1 = n1.PadLeft(max, '0');
n2 = n2.PadLeft(max, '0');
if (s1.Equals(s2)) // we have to compare the version
// which is now left-padded with 0s.
{
return ((new CaseInsensitiveComparer()).Compare(n1, n2));
}
else // not the same base file name. So the version does not matter.
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
else // not versioned
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
}
我不喜歡的P/Invoke。它總是讓我覺得它是某種黑客;) 謝謝。我會看看它。對我的例外問題有任何想法? – user51710 2009-01-08 20:49:18