سؤال

System.IO.Directory.GetFiles() يعود أ string[].ما هو ترتيب الفرز الافتراضي للقيم التي تم إرجاعها؟أفترض بالاسم، ولكن إذا كان الأمر كذلك، فما مدى تأثير الثقافة الحالية عليه؟هل يمكنك تغييره إلى شيء مثل تاريخ الإنشاء؟

تحديث: يشير MSDN إلى أن ترتيب الفرز غير مضمون لـ .Net 3.5، ولكن الإصدار 2.0 من الصفحة لا يذكر أي شيء على الإطلاق ولن تساعدك أي من الصفحتين على الفرز حسب أشياء مثل وقت الإنشاء أو التعديل.يتم فقدان هذه المعلومات بمجرد حصولك على المصفوفة (تحتوي على سلاسل فقط).يمكنني إنشاء مُقارن يمكنه التحقق من كل ملف يتم الحصول عليه، ولكن هذا يعني الوصول إلى نظام الملفات بشكل متكرر عندما يُفترض أن طريقة .GetFiles() تقوم بذلك بالفعل.يبدو غير فعال للغاية.

هل كانت مفيدة؟

المحلول

إذا كنت مهتمًا بخصائص الملفات مثل CreationTime، فمن المنطقي استخدام System.IO.DirectoryInfo.GetFileSystemInfos().يمكنك بعد ذلك فرزها باستخدام إحدى طرق الامتداد في System.Linq، على سبيل المثال:

DirectoryInfo di = new DirectoryInfo("C:\\");
FileSystemInfo[] files = di.GetFileSystemInfos();
var orderedFiles = files.OrderBy(f => f.CreationTime);

تحرير - آسف، لم ألاحظ علامة .NET2.0 لذا تجاهل فرز LINQ.لا يزال اقتراح استخدام System.IO.DirectoryInfo.GetFileSystemInfos() قائمًا بالرغم من ذلك.

نصائح أخرى

في .NET 2.0، ستحتاج إلى استخدام Array.Sort لفرز FileSystemInfos.

بالإضافة إلى ذلك، يمكنك استخدام مندوب المقارنة لتجنب الاضطرار إلى الإعلان عن فئة للمقارنة فقط:

DirectoryInfo dir = new DirectoryInfo(path);
FileSystemInfo[] files = dir.GetFileSystemInfos();

// sort them by creation time
Array.Sort<FileSystemInfo>(files, delegate(FileSystemInfo a, FileSystemInfo b)
                                    {
                                        return a.LastWriteTime.CompareTo(b.LastWriteTime);
                                    });

إليك حل VB.Net الذي استخدمته.

قم أولاً بإنشاء فصل دراسي لمقارنة التواريخ:

Private Class DateComparer
    Implements System.Collections.IComparer

    Public Function Compare(ByVal info1 As Object, ByVal info2 As Object) As Integer Implements System.Collections.IComparer.Compare
        Dim FileInfo1 As System.IO.FileInfo = DirectCast(info1, System.IO.FileInfo)
        Dim FileInfo2 As System.IO.FileInfo = DirectCast(info2, System.IO.FileInfo)

        Dim Date1 As DateTime = FileInfo1.CreationTime
        Dim Date2 As DateTime = FileInfo2.CreationTime

        If Date1 > Date2 Then Return 1
        If Date1 < Date2 Then Return -1
        Return 0
    End Function
End Class

ثم استخدم المقارن أثناء فرز المصفوفة:

Dim DirectoryInfo As New System.IO.DirectoryInfo("C:\")
Dim Files() As System.IO.FileInfo = DirectoryInfo.GetFiles()
Dim comparer As IComparer = New DateComparer()
Array.Sort(Files, comparer)

Dim Files() As String
Files = System.IO.Directory.GetFiles("C:\")
Array.Sort(Files)

من msdn:

ترتيب أسماء الملفات التي تم إرجاعها غير مضمون؛استخدم طريقة Sort() إذا كان ترتيب الفرز محددًا مطلوبًا.

ال نوع() الطريقة هي Array.Sort()‎ القياسية، والتي تأخذ IComparables (من بين عمليات التحميل الزائدة الأخرى)، لذلك إذا قمت بالفرز حسب تاريخ الإنشاء، فسوف تتعامل مع الترجمة بناءً على إعدادات الجهاز.

أنت على حق، الافتراضي هو اسمي تصاعدي.الطريقة الوحيدة التي وجدتها لتغيير ترتيب الفرز هي إنشاء جدول بيانات من مجموعة FileInfo.

يمكنك بعد ذلك استخدام DefaultView من جدول البيانات وفرز الدليل باستخدام طريقة الفرز.

يعد هذا أمرًا متورطًا للغاية وبطيئًا إلى حد ما ولكني آمل أن ينشر شخص ما حلاً أفضل.

يمكنك تطبيق iComparer مخصص للقيام بالفرز.اقرأ معلومات الملف للملفات وقارنها كما تريد.

IComparer comparer = new YourCustomComparer();
Array.Sort(System.IO.Directory.GetFiles(), comparer);

معلومات msdn واجهة IComparer

إصدار VB.Net أكثر إيجازًا... جميل جدًا.شكرًا لك.لاجتياز القائمة بترتيب عكسي، أضف الطريقة العكسية...

For Each fi As IO.FileInfo In filePaths.reverse
  ' Do whatever you wish here
Next

ال وثائق MSDN ينص على أنه لا يوجد ضمان لأي أمر على قيم الإرجاع.يجب عليك استخدام طريقة الفرز ().

يمكنك كتابة واجهة IComparer مخصصة للفرز حسب تاريخ الإنشاء، ثم تمريرها إلى Array.Sort.ربما تريد أيضًا إلقاء نظرة على StrCmpLogical، وهو ما يُستخدم للقيام بالفرز الذي يستخدمه Explorer (فرز الأرقام بشكل صحيح مع النص).

إذا كنت تريد الفرز حسب شيء مثل تاريخ الإنشاء، فربما تحتاج إلى استخدام DirectoryInfo.GetFiles ثم فرز المصفوفة الناتجة باستخدام المسند المناسب.

مجرد فكرة.أحب العثور على طريقة سهلة ومحاولة إعادة استخدام الموارد المتاحة بالفعل.إذا كنت سأقوم بفرز الملفات، كنت سأقوم فقط بإنشاء عملية وإجراء النظام على "DIR [x:\Folders\SubFolders*.*] /s /b /on" والتقاط الإخراج.

باستخدام أمر DIR الخاص بالنظام، يمكنك الفرز حسب:

/O          List by files in sorted order.
sortorder    N  By name (alphabetic)       S  By size (smallest first)
             E  By extension (alphabetic)  D  By date/time (oldest first)
             G  Group directories first    -  Prefix to reverse order

The /S switch includes sub folders

لست متأكدًا مما إذا كان D = حسب التاريخ/الوقت يستخدم LastModifiedDate أو FileCreateDate.ولكن إذا كان ترتيب الفرز المطلوب مدمجًا بالفعل في أمر DIR، فسأحصل على ذلك عن طريق الاتصال بـ syscall.وهو سريع.أنا مجرد شخص كسول ;)

بعد قليل من البحث على Google، وجدت مفتاحًا للفرز حسب تاريخ/وقت معين: -

/t [[:]TimeField] : Specifies which time field to display or use for sorting. The following list describes each of the values you can use for TimeField. 

Value Description 
c : Creation
a : Last access
w : Last written

نسخة VB.Net أكثر إيجازًا، إذا كان أي شخص مهتمًا

Dim filePaths As Linq.IOrderedEnumerable(Of IO.FileInfo) = _
  New DirectoryInfo("c:\temp").GetFiles() _
   .OrderBy(Function(f As FileInfo) f.CreationTime)
For Each fi As IO.FileInfo In filePaths
  ' Do whatever you wish here
Next
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top