2012-09-03 17 views
11

नई आई/ओ API के साथ जावा 7 में, वहाँ पिछले संशोधन दिनांक से एक निर्देशिका की सामग्री को सूचीबद्ध करने के लिए एक आसान तरीका है? असल में मुझे केवल उस फ़ाइल को प्राप्त करने की आवश्यकता है जिसे सबसे लंबे समय तक संशोधित नहीं किया गया था (अंतिम संशोधित आरोही द्वारा क्रमबद्ध करें, पहले फ़ाइल नाम लें)।अंतिम संशोधित द्वारा क्रमबद्ध निर्देशिका में फ़ाइलें प्राप्त करें?

उत्तर

16

कोई वास्तविक "आसान तरीका" यह करने के लिए नहीं है, लेकिन यह संभव है:

List<Path> files = new ArrayList<>(); 
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { 
    for(Path p : stream) { 
     files.add(p); 
    } 
} 

Collections.sort(files, new Comparator<Path>() { 
    public int compare(Path o1, Path o2) { 
     try { 
      return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2)); 
     } catch (IOException e) { 
      // handle exception 
     } 
    } 
}); 

यह फ़ाइलों soonest संशोधित फ़ाइलों पिछले सॉर्ट होगा। DirectoryStream एस उपनिर्देशिका के माध्यम से पुनरावृत्त नहीं करते हैं।

+0

पूर्ण समाधान के लिए धन्यवाद। File.listFiles() आपके कोड को छोटा कर सकता है :-) –

+1

@ stefan.at.wpf लेकिन फिर यह आपके अनुरोध के अनुसार एनआईओ 2 का उपयोग नहीं करेगा – Jeffrey

+0

आह ठीक है, क्षमा करें, उसे नोटिस नहीं किया। मुझे एनआईओ की आवश्यकता नहीं है, मैं बस सोच रहा था कि क्या एनआईओ एक आसान समाधान प्रदान करेगा ;-) –

0
lastModified() 

समय उस फ़ाइल इस सार पथ नाम से दर्शाया जाने वाला अंतिम बार संशोधित किया गया था देता है।

Java 7 - IO API

+0

धन्यवाद, लेकिन 100 फाइलों के साथ एक निर्देशिका से मुझे सबसे पुराना प्राप्त करने की आवश्यकता है, बस सोच रहा है, अगर सभी अंतिम संशोधित मानों की मैन्युअल रूप से तुलना करने से बेहतर तरीका है, उदा। सॉर्टिंग दिशा के आधार पर केवल एक सॉर्टिंग विकल्प पास करना और फिर सूची की पहली या अंतिम प्रविष्टि लेना। –

+0

यह जानने के लिए कि कौन सी फाइल नवीनतम/सबसे पुरानी है, सभी फाइलों पर लूप करना जरूरी है। फाइलफिल्टर करता है जो (मेरे ज्ञान के रूप में) है। जेडीवीफ़ के पद में उल्लिखित एकमात्र चीज (संपादित करें: संभवतः इसे प्राप्त करने के कई तरीके), इस फ़ाइल को 'f = नई फ़ाइल ("") के रूप में एक तुलनित्र बनाना होगा; Arrays.sort (f.listFiles(), नई तुलनाकारी () { सार्वजनिक पूर्णांक तुलना (फ़ाइल O1, फ़ाइल o2) { वापसी (int) (o1.lastModified() - o2.lastModified()); } }); वापसी एफ [0]; ' – atomman

0

आप http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter उपयोग कर सकते हैं) और आपूर्ति http://docs.oracle.com/javase/1.5.0/docs/api/java/io/FileFilter.html

तो http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified() की तुलना और आप

काम हो गया है, तो आप प्रदर्शन के बारे में परवाह है - तो बस अधिकतम/न्यूनतम के साथ एक ले फ़ाइल सूची, कि आप हे (एन) जटिलता निर्देशिका के फ़ाइल वस्तु पर

2

उपयोग listFiles() दे देंगे से मूल्य। सरणी को एक सरणी सूची में कनवर्ट करें। फिर संग्रह क्लास पर एक स्थिर सॉर्ट विधि का उपयोग करके उन्हें एक कस्टम तुलनात्मक के साथ सॉर्ट करें जो फ़ाइलों पर getTotalSpace() विधि का उपयोग करता है। संपादित करें: getTotalSpace के बजाय lastModified का उपयोग करें।

0

नोट: इस समाधान के लिए गुवा की आवश्यकता है।

जावा आईओ/एनआईओ एपीआई निर्देशिका सूची में निम्न स्तर की पहुंच प्रदान करता है, लेकिन कोई प्रसंस्करण नहीं किया जाता है, जो कॉलर को छोड़ दिया जाता है। नई जे ava7 एनआईओ निर्देशिकास्ट्रीम में आगे की प्रक्रिया के लिए निर्देशिका सूची तक पहुंचने पर न्यूनतम पदचिह्न है, उदा। छँटाई।

यहाँ मेरी समाधान है: DirectoryStream से फाइल पढ़ें और (वैकल्पिक) धारा से सीमित आकार के साथ एक क्रमबद्ध कतार निर्माण। कतार से सबसे पुराने/नवीनतम तत्व लौटें।

private void listFilesOldestFirst(final File directory, final Integer maxNumberOfFiles) { 

    final Builder<File> builder = 
      MinMaxPriorityQueue 
      .orderedBy(LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); 
    if(maxNumberOfFiles != null) { 
     builder.maximumSize(maxNumberOfFiles); 
    } 

    // queue with constant space, if maxNumberOfFiles is set, otherwise behaves like an unbound queue with an O(log n) penalty for insertion 
    final MinMaxPriorityQueue<File> oldestFiles = builder.create(); 

    try(DirectoryStream<Path> stream = Files.newDirectoryStream(directory.toPath())) { 
     for(final Path p : stream) { 
      oldestFiles.add(p.toFile()); 
     } 
    } catch (final IOException e) { 
     throw new RuntimeException(e); 
    } 

    final File[] fileArray = oldestFiles.toArray(new File[]{}); 
    Arrays.sort(fileArray, oldestFiles.comparator()); 
    // ... use fileArray 

    final ArrayList<File> arrayList = Lists.newArrayList(oldestFiles); 
    Collections.sort(arrayList, oldestFiles.comparator()); 
    // ... use arrayList 

} 

ये निर्भरता अमरूद MinMaxPriorityQueue और FileComparator के लिए आवश्यक हैं:

<dependency> 
     <groupId>com.google.guava</groupId> 
     <artifactId>guava</artifactId> 
     <version>18.0</version> 
    </dependency> 
    <dependency> 
     <groupId>commons-io</groupId> 
     <artifactId>commons-io</artifactId> 
     <version>2.4</version> 
    </dependency> 

तुम भी की फिल्टर पैरामीटर मिल सकता है Files.newDirectoryStream उपयोगी:

final Filter<Path> sampleFilter = new Filter<Path>() { 
     @Override 
     public boolean accept(final Path entry) throws IOException { 
      return true; // see commons-io -> FileFilterUtils 
     } 
    }; 

    ... 
    Files.newDirectoryStream(directory.toPath(), sampleFilter) 
4

जेफरी के उत्तर की थोड़ी "स्ट्रीम" आईर भिन्नता, जो कुछ भी आसानी से मिल सकती है। पूर्णता के लिए पोस्टिंग।

try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) { 
    StreamSupport.stream(files.spliterator(), false) 
     .sorted((o1, o2) -> { 
      try { 
       return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2)); 
      } catch (IOException ex) { 
       ... 
      } 
     }) 
     .filter(file -> Files.isRegularFile(file)) 
     .forEach(file -> { 
     }); 
} 
संबंधित मुद्दे