.NET का उपयोग करके निर्देशिका में सबसे हाल की फ़ाइल कैसे खोजें, और बिना लूपिंग के?


142

मुझे एक निर्देशिका में सबसे हाल ही में संशोधित फ़ाइल खोजने की आवश्यकता है।

मुझे पता है कि मैं एक फ़ोल्डर में हर फ़ाइल के माध्यम से लूप कर सकता हूं और तुलना कर सकता हूं File.GetLastWriteTime, लेकिन क्या बिना लूपिंग के ऐसा करने का एक बेहतर तरीका है?


18
कोई भी बेहतर तरीका नहीं है जो लूपिंग से बचता है। यहां तक ​​कि LINQ का उपयोग करते हुए लूपिंग को कुछ गहरी कार्यक्षमता में छिपा दिया जाता है जहां आप इसे सीधे नहीं देख सकते हैं।
ओलिवर

1
यदि आप संपूर्ण फाइल सिस्टम पर सबसे हाल ही में संशोधित फ़ाइल (ओं) को ढूंढना चाहते थे, तो NTFS चेंज जर्नल उपयोगी होगा। सी # से उपयोग करने के लिए बहुत कठिन है, हालांकि।
बेन वोइगेट

जवाबों:


318

इस जैसे किसी और के बारे में क्या राय है...

var directory = new DirectoryInfo("C:\\MyDirectory");
var myFile = (from f in directory.GetFiles()
             orderby f.LastWriteTime descending
             select f).First();

// or...
var myFile = directory.GetFiles()
             .OrderByDescending(f => f.LastWriteTime)
             .First();

84
व्यक्तिगत रूप से, मुझे लगता है कि गैर-शर्करा वाले संस्करण को पढ़ना आसान है:directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
जॉर्न शॉ-रोड

6
हाँ, मैं ज्यादातर समय भी सहमत हूँ - लेकिन जब क्वेरी सिंटैक्स उदाहरण देता है तो यह थोड़ा अधिक स्पष्ट होता है कि यह एक linq क्वेरी है। मैं स्पष्ट करने के लिए दोनों विकल्पों के साथ उदाहरण को अपडेट करूंगा।
स्कॉट आइवी

3
धन्यवाद! अब मुझे सिर्फ अपने बॉस को समझाने की आवश्यकता है कि हमें .net 2.0 से अपग्रेड करने की प्रक्रिया में तेजी लाई जाए ताकि मैं Linq :) का उपयोग कर
सकूं

3
आप थोड़ा अतिरिक्त काम के साथ 2.0 SP1 के साथ linq का उपयोग कर सकते हैं - बस 3.5 से System.Core.dll फ़ाइल का संदर्भ लें, और इसे "स्थानीय कॉपी करें" पर सेट करें
स्कॉट Ivey

8
FirstOrDefault()इसके बजाय इस का उपयोग नहीं करना चाहिए First()? InvalidOperationExceptionयदि निर्देशिका खाली है तो उत्तरार्द्ध का कारण होगा ।
टोबियास जे

20

यदि आप पुनरावर्ती खोज करना चाहते हैं, तो आप कोड के इस सुंदर टुकड़े का उपयोग कर सकते हैं:

public static FileInfo GetNewestFile(DirectoryInfo directory) {
   return directory.GetFiles()
       .Union(directory.GetDirectories().Select(d => GetNewestFile(d)))
       .OrderByDescending(f => (f == null ? DateTime.MinValue : f.LastWriteTime))
       .FirstOrDefault();                        
}

बस इसे निम्न तरीके से कॉल करें:

FileInfo newestFile = GetNewestFile(new DirectoryInfo(@"C:\directory\"));

और बस। एक FileInfoउदाहरण देता है या nullयदि निर्देशिका खाली है।


12
या आप पुनरावर्ती खोज विकल्प का उपयोग कर सकते हैं ।
रिक्शा

17

उपरोक्त पहले एक पर विस्तार करते हुए, यदि आप एक निश्चित पैटर्न की खोज करना चाहते हैं, तो आप निम्नलिखित कोड का उपयोग कर सकते हैं:

string pattern = "*.txt";
var dirInfo = new DirectoryInfo(directory);
var file = (from f in dirInfo.GetFiles(pattern) orderby f.LastWriteTime descending select f).First();

हमें वो चाहिये था। धन्यवाद।
ऐशिलॉन

10

एक गैर LINQ संस्करण:

/// <summary>
/// Returns latest writen file from the specified directory.
/// If the directory does not exist or doesn't contain any file, DateTime.MinValue is returned.
/// </summary>
/// <param name="directoryInfo">Path of the directory that needs to be scanned</param>
/// <returns></returns>
private static DateTime GetLatestWriteTimeFromFileInDirectory(DirectoryInfo directoryInfo)
{
    if (directoryInfo == null || !directoryInfo.Exists)
        return DateTime.MinValue;

    FileInfo[] files = directoryInfo.GetFiles();
    DateTime lastWrite = DateTime.MinValue;

    foreach (FileInfo file in files)
    {
        if (file.LastWriteTime > lastWrite)
        {
            lastWrite = file.LastWriteTime;
        }
    }

    return lastWrite;
}

/// <summary>
/// Returns file's latest writen timestamp from the specified directory.
/// If the directory does not exist or doesn't contain any file, null is returned.
/// </summary>
/// <param name="directoryInfo">Path of the directory that needs to be scanned</param>
/// <returns></returns>
private static FileInfo GetLatestWritenFileFileInDirectory(DirectoryInfo directoryInfo)
{
    if (directoryInfo == null || !directoryInfo.Exists)
        return null;

    FileInfo[] files = directoryInfo.GetFiles();
    DateTime lastWrite = DateTime.MinValue;
    FileInfo lastWritenFile = null;

    foreach (FileInfo file in files)
    {
        if (file.LastWriteTime > lastWrite)
        {
            lastWrite = file.LastWriteTime;
            lastWritenFile = file;
        }
    }
    return lastWritenFile;
}

1
क्षमा करें, इस तथ्य को नहीं देखा कि आप लूप नहीं करना चाहते थे। वैसे भी ... शायद यह किसी को कुछ इसी तरह की खोज करने में मदद करेगा
टिमोथी

3
यह कोड संकलित नहीं करता है। - lastUpdatedFile एक सरणी नहीं होनी चाहिए। - LastUpdate के लिए प्रारंभिक मान अमान्य है (0001/0/0)।
लार्स ए। ब्रेकेन

4

लघु और सरल :

new DirectoryInfo(path).GetFiles().OrderByDescending(o => o.LastWriteTime).FirstOrDefault();

3

थोड़ी देर हो गई लेकिन ...

आपका कोड काम नहीं करेगा, क्योंकि list<FileInfo> lastUpdateFile = null; और बाद में lastUpdatedFile.Add(file);इसलिए NullReference अपवाद को फेंक दिया जाएगा। कार्य संस्करण होना चाहिए:

private List<FileInfo> GetLastUpdatedFileInDirectory(DirectoryInfo directoryInfo)
{
    FileInfo[] files = directoryInfo.GetFiles();
    List<FileInfo> lastUpdatedFile = new List<FileInfo>();
    DateTime lastUpdate = DateTime.MinValue;
    foreach (FileInfo file in files)
    {
        if (file.LastAccessTime > lastUpdate)
        {
            lastUpdatedFile.Add(file);
            lastUpdate = file.LastAccessTime;
        }
    }

    return lastUpdatedFile;
}

धन्यवाद


2

आप FileSystemWatcher के साथ नई फ़ाइल गतिविधि पर प्रतिक्रिया कर सकते हैं ।


1
यह काम नहीं करता है क्योंकि किसी फ़ाइल को संशोधित किया जा सकता है जबकि उसका आवेदन नहीं चल रहा है।
फ्रांसिस बी।

1
उन्होंने इस तरह का विवरण नहीं दिया ... हमें कैसे पता चलेगा कि यह एक स्थायी ऐप नहीं है?
स्कॉट मारलो

1
हम नहीं करते हैं, लेकिन स्कॉट के पास बेहतर समाधान है जो दोनों मामलों में काम करता है।
बद्रो

इसके अलावा, ध्यान दें कि FSW अधिकांश नेटवर्क साझा किए गए फ़ोल्डरों के साथ काम नहीं करेगा।
bkqc

2

एक और तरीका यदि आप उपयोग कर रहे हैं Directory.EnumerateFilesऔर पहले द्वारा संशोधित नवीनतम फाइलों को पढ़ना चाहते हैं।

foreach (string file in Directory.EnumerateFiles(fileDirectory, fileType).OrderByDescending(f => new FileInfo(f).LastWriteTime))

}

1

यहां एक संस्करण है जो प्रत्येक उपनिर्देशिका से सबसे हाल की फ़ाइल प्राप्त करता है

List<string> reports = new List<string>();    
DirectoryInfo directory = new DirectoryInfo(ReportsRoot);
directory.GetFiles("*.xlsx", SearchOption.AllDirectories).GroupBy(fl => fl.DirectoryName)
.ForEach(g => reports.Add(g.OrderByDescending(fi => fi.LastWriteTime).First().FullName));

0
private List<FileInfo> GetLastUpdatedFileInDirectory(DirectoryInfo directoryInfo)
{
    FileInfo[] files = directoryInfo.GetFiles();
    List<FileInfo> lastUpdatedFile = null;
    DateTime lastUpdate = new DateTime(1, 0, 0);
    foreach (FileInfo file in files)
    {
        if (file.LastAccessTime > lastUpdate)
        {
            lastUpdatedFile.Add(file);
            lastUpdate = file.LastAccessTime;
        }
    }

    return lastUpdatedFile;
}

0

मैं यह करता हूं कि मेरे ऐप्स का एक गुच्छा है और मैं इस तरह के एक बयान का उपयोग करता हूं:

  var inputDirectory = new DirectoryInfo("\\Directory_Path_here");
  var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();

यहां से आपको "inputDirectory" चर की निर्देशिका में सबसे हाल ही में सहेजी गई / जोड़ी गई / अपडेट की गई फ़ाइल का नाम होगा। अब आप इसे एक्सेस कर सकते हैं और वही कर सकते हैं जो आप इसके साथ चाहते हैं।

उम्मीद है की वो मदद करदे।


इसे जोड़ने के लिए, यदि आपका लक्ष्य फ़ाइल पथ को वापस प्राप्त करना है, और आप FirstOrDefault का उपयोग कर रहे हैं क्योंकि यह संभव है कि कोई परिणाम नहीं हैं, तो आप FullName गुण पर नल-सशर्त ऑपरेटर का उपयोग कर सकते हैं। इससे पहले कि आप FullName कॉल करने से पहले FirstOrDefault से FileInfo को बचाने के बिना आपको अपने रास्ते के लिए "शून्य" वापस कर देंगे। string path = new DirectoryInfo (path) .GetFiles ()। OrderByDescending (o => o.LastWriteTime) .FirstOrDefault (); FullName;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.