Сортировка файлов по дате
Я использую такой код для сравнения файлов для сортировки по дате..
FileInfo f = new FileInfo(name1);
FileInfo f1 = new FileInfo(name2);
if (f.Exists && f1.Exists)
output = DateTime.Compare(f.LastWriteTime, f1.LastWriteTime);
Есть ли лучший и более быстрый способ сортировки по дате?
Одновременно я могу сравнить только 2 предмета...
Я не мог отсортировать, получив все файлы из каталога.
8 ответов
Вы можете использовать LINQ:
var sortedFiles = new DirectoryInfo(@"D:\samples").GetFiles()
.OrderBy(f => f.LastWriteTime)
.ToList();
DirectoryInfo directoryInfo = new DirectoryInfo(@"D:\Temp");
var result = directoryInfo.GetFiles("*.*",SearchOption.AllDirectories).OrderBy(t => t.LastWriteTime).ToList();
Как насчет использования Array.Sort?
string[] fileNames = Directory.GetFiles("directory ", "*.*");
DateTime[] creationTimes = new DateTime[fileNames.Length];
for (int i = 0; i < fileNames.Length; i++)
creationTimes[i] = new FileInfo(fileNames[i]).CreationTime;
Array.Sort(creationTimes, fileNames);
ВАЖНО - При заказе LastWriteTime следует отметить, что если файл никогда не изменялся, эта дата может возвращаться 1601 или 1600. Вот что говорит MSDN:
Если файл, описанный в параметре пути, не существует, этот метод возвращает 12:00 полуночи, 1 января, 1601 г. (CE), всемирное координированное время (UTC), скорректированное на местное время.
Если ваш часовой пояс PST, как и у меня, дата будет на самом деле 31.12.1600. Чтобы обойти это и написать более надежный код, вы можете рассмотреть что-то вроде этого:
.OrderByDescending(f => f.LastWriteTime.Year <= 1601 ? f.CreationTime : f.LastWriteTime)
Это еще один способ сделать это для всего каталога:dateCompareFileInfo
if (Directory.Exists(DIRECTORY_NAME))
{
DirectoryInfo di = new DirectoryInfo(DIRECTORY_NAME);
FileInfo[] logFiles = di.GetFiles("AN-10-log.txt*");
DateCompareFileInfo dateCompareFileInfo = new DateCompareFileInfo();
Array.Sort(logFiles, dateCompareFileInfo);
}
И вам нужен новый класс DateCompareFileInfo, который реализует IComparer:
class DateCompareFileInfo : IComparer<FileInfo>
{
/// <summary>
/// Compare the last dates of the File infos
/// </summary>
/// <param name="fi1">First FileInfo to check</param>
/// <param name="fi2">Second FileInfo to check</param>
/// <returns></returns>
public int Compare(FileInfo fi1, FileInfo fi2)
{
int result;
if (fi1.LastWriteTime == fi2.LastWriteTime)
{
result = 0;
}
else if (fi1.LastWriteTime < fi2.LastWriteTime)
{
result = 1;
}
else
{
result = -1;
}
return result;
}
}
Это преобразует результат в читаемый класс с помощью объекта SSIS:
var directory = Dts.Variables["User::SourceDir"].Value.ToString();
DirectoryInfo directoryInfo = new DirectoryInfo(directory);
var result = directoryInfo.GetFiles("*.xml", SearchOption.AllDirectories).OrderBy(t => t.LastWriteTime).ToList();
DataTable dsSorted = new DataTable();
DataColumn dc = new DataColumn("Value");
dsSorted.Columns.Add(dc);
foreach (FileInfo item in result)
{
DataRow dr = dsSorted.NewRow();
dr[0] = directory + item ;
dsSorted.Rows.Add(dr);
}
// lastModified = file.LastWriteTime;
Dts.Variables["User::FileNamesSorted"].Value = dsSorted;
// MessageBox.Show(Dts.Variables["User::FileNamesSorted"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
// Compare LastWriteTimeUtc of FileInfos
private class FileInfoDateComparer : IComparer<FileInfo> {
//
public long direction = 1;
//
public FileInfoDateComparer( bool ascending ) {
direction = ascending ? 1 : -1;
}
//
public int Compare( FileInfo fi1, FileInfo fi2 ) {
long d = direction * ( fi1.LastWriteTimeUtc.Ticks - fi2.LastWriteTimeUtc.Ticks );
return d < 0 ? -1 : d > 0 ? 1 : 0;
}
}
//
//
private static FileInfo[] SortByDate( FileInfo[] afi, bool ascending ) {
if ( null != afi ) {
if ( 0 < afi.Length ) {
var c = new FileInfoDateComparer( ascending );
Array.Sort( afi, c );
}
}
return afi;
}
Вот решение, которое я нашел в социальной сети MSDN.
DirectoryInfo di = new DirectoryInfo(@"c:\my-directory");
FileInfo[] files = di.GetFiles(@"*.*");
Array.Sort(files, (x, y) => Comparer<DateTime>.Default.Compare(x.LastWriteTime, y.LastWriteTime));