Сортировка имен файлов в каталоге, дающая неправильно упорядоченные результаты - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть файлы в каталоге с такими именами файлов:

Пакет 1.10.18.xlsx
Партия 2.10.18.xlsx
...
Пакет 31.10.18.xlsx

Как видите, у них есть такой шаблон: Пакет dd.mm.yy.xlsx

Мне нужно обработать их в порядке, указанном в именах файлов.

Код пока:

private void processFiles(string BatchFilePath)
{
     IOrderedEnumerable<string> fileEntries = 
                Directory.GetFiles(BatchFilePath, "Batch *.xlsx")
                .OrderBy(f => GetFileDay(f));

     foreach (string fileName in fileEntries)
     {
        Console.WriteLine("Processing File " + Path.GetFileName(fileName));

        // Code that read and process files 
     }

}

private int GetFileDay(string file)
{
    string s1=  file.Substring(7, 2);
    if (s1.Substring(1) == ".")
        s1 = s1.Substring(0, 1);
     return int.Parse(s1);
}

Код не работает. Он по-прежнему дает мне файлы с именами в неправильном порядке, как показано ниже:

Пакет 25.10.18.xlsx
Партия 22.10.18.xlsx ...
Пакет 9.10.18.xlsx
Пакет 3.10.18.xlsx
...

Ответы [ 4 ]

0 голосов
/ 02 ноября 2018

Используйте регулярные выражения для анализа даты по имени файла и сортировки по дате и времени. Вот модифицированный код.

public static IOrderedEnumerable<string> GetFiles(string batchFilePath)
        {
            if (Directory.Exists(batchFilePath))
            {
                var directoryInfo = new DirectoryInfo(batchFilePath);
                var fileEntries = directoryInfo.GetFiles(@"Batch *.xlsx").Select(x => x.Name).OrderBy(f => GetFileDay(f));
                return fileEntries;
            }

            return null;
        }

    private static DateTime GetFileDay(string file)
    {
        var date = default(DateTime);
        var extractedDate = Regex.Match(file, @"(\W\S*(\d[\d]{0,2}))").Value;
        extractedDate = extractedDate.Replace(".", "-").Trim();           
        DateTime.TryParseExact(extractedDate, "d-MM-yy", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out date);
        return date;
    }
0 голосов
/ 02 ноября 2018

Учитывая, что ваша коллекция файлов будет IEnumerable<T>, будет работать сортировка по реальной дате [не строка!] Вашей культуры

var l  = new List<string>()
{
   "c:\\dev\\Batch 1.10.18.xlsx", 
   "c:\\dev\\Batch 2.10.18.xlsx", 
   "c:\\dev\\Batch 31.10.18.xlsx"
};

var ci = CultureInfo.GetCultureInfo("fr-FR"); // pick culture is same as pick format. You need to pre-define one
var r = l.Select(x=>new{name = x, parts = Path.GetFileNameWithoutExtension(x).Split(" .".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)}).
        Select(a=> new {name = a.name, date = DateTime.Parse(a.parts[1] + "/" + a.parts[2] + "/" + a.parts[3], ci)}).
        OrderBy(x => x.date); //OrderByDescending(x => x.date);

r.ToList().ForEach(x => Console.WriteLine(x.name));

Выход

Пакет 1.10.18.xlsx
Партия 2.10.18.xlsx
Пакет 31.10.18.xlsx

Это можно сделать более эффективно, но менее линейно.

0 голосов
/ 02 ноября 2018

Вы можете использовать следующее регулярное выражение. Затем вы можете сделать OrderBy / OrderByDescending на Linq:

Regex r = new Regex(@"\d{1,2}.\d{1,2}.\d{2}");
var orderByDateList = items.Where(po => r.IsMatch(po)).OrderByDescending(po => DateTime.ParseExact(r.Match(po).Value, "d.M.yy", null)).ToList(); // lines that match date pattern
0 голосов
/ 02 ноября 2018

Разобрать строку (например, "1.10.18") в вещественное значение DateTime (2018-10-01):

DateTime GetFileDay(string fileNameOrPath)
{
    string fileNameWithoutExt = System.IO.Path.GetFileNameWithoutExtension(fileNameOrPath);
    return DateTime.ParseExact(fileNameWithoutExt.Replace("Batch ", ""), "d.M.yy", null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...