Résolu au bas de mon message.Problème IComparer + Comment trier un tableau de chaînes naturellement (FILE_10> FILE_2) dans .NET?
Ou plus précisément:
J'ai un tas d'objets FileInfo (je besoin des objets FileInfo pour exclure caché, système et fichiers de point d'analyse).
J'ai besoin de trier FileInfo [] naturellement en fonction de leur FileInfo.FullName. Donc FILE_10.ext devrait venir après FILE_2.ext. Heureusement, FileInfo [] contient des fichiers d'une seule extension.
J'ai mis en place un comparateur:
/// <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));
}
}
}
Maintenant, le problème se pose que int.Parse jette un OverflowException que je n'ai pas pu attraper au bon moment (il se reproduit sur la ligne de la déclaration de retour pour une raison et je ne peux pas le gérer intelligemment à un niveau plus haut parce qu'il n'arrive jamais là-bas).
La question est: Y a-t-il un pré-encaissement pour ce genre de chose? Et quelle pourrait être la raison pour laquelle l'exception se présente dans des endroits drôles?
Indicatif téléphonique:
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 jette OverflowException quand il rencontre un trop grand nombre. Cela ne devrait pas arriver de façon régulière, mais je le veux couvert. EDIT2: J'ai fini par ajuster mon propre Comparer. Je suis parti de int.Parse et juste à gauche avec des zéros pour la comparaison. Code ici:
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));
}
}
}
Je n'aime pas P/Invoke. Ça me fait toujours penser que c'est une sorte de hack;) Merci. Je vais y jeter un coup d'oeil. Des pensées sur mon problème d'exception? – user51710
Encore une fois, merci. J'ai fini par mettre en place ma propre trieuse de travail. – user51710