2016-07-08 32 views
0

Mit erhalte ich eine DirectoryStream von Dateien in meinem dir die pattern entsprechen. Aber ich bin nicht an all diesen Dateien interessiert. Ich möchte nur die neueste und ich weiß, dass der Dateiname der neuesten ist der größte Dateiname in Bezug auf lexikographische Reihenfolge (weil der Zeitstempel enthalten ist). Was ist der einfachste Weg, um diese Datei zu bekommen? Ist es immer der letzte, der in meinem Strom kommt? Was würden Sie tun?Get</p> <pre><code>DirectoryStream<Path> stream = Files.newDirectoryStream(dir,pattern); </code></pre> <p>die aktuellste Datei

+0

Vorausgesetzt, dass Ihre Dateien in chronologischer Reihenfolge auf Zeitstempel basieren und angenommen, dass newDirectoryStream sie sinnvoll sortiert, dann, ja, es wäre der letzte Eintrag in Ihrem Stream. – ManoDestra

+0

Ich gehe davon aus, dass der Dateiname _starts with_ der Zeitstempel ist. Ist das richtig? –

+0

@ManoDestra Meine Frage ist, wenn newDirectoryStream sie bestellt. Wenn es sie bestellt, dann weiß ich durch mein Dateinamenskonzept, dass es die letzte Datei ist. –

Antwort

1

Hallo hier ist ein Code-Fragment, das glaube ich tut, was Sie brauchen.

 DirectoryStream<Path> stream = Files.newDirectoryStream(dir,pattern); 
     Path latestPath=null; 
     FileTime latestTime = null; 
     for (Path path:stream) { 
      BasicFileAttributes attribs = Files.readAttributes(path, BasicFileAttributes.class); 
      FileTime time = attribs.creationTime(); 
      if (latestTime==null) { 
       latestPath = path; 
       latestTime = time; 
      } 
      else { 
       if (time.compareTo(latestTime)>0) { 
        latestTime = time; 
        latestPath = path; 
       } 
      } 
     } 

Java 8 Version:

DirectoryStream<Path> stream = Files.newDirectoryStream(null,""); 
List<Path> list = new ArrayList()<>(); 
stream.forEach(list::add); 
list.stream() 
      .max((t,q)->{ 
          BasicFileAttributes attribs1 = Files.readAttributes(t, BasicFileAttributes.class); 
          BasicFileAttributes attribs2 = Files.readAttributes(q, BasicFileAttributes.class); 
        return attribs1.creationTime().compareTo(attribs2.creationTime());}); 

Ich sehe nicht verantwortlich jede mögliche Weise, die wir gerade von Iterator streamen, so dass das Beste ist, ich mit oben kommen kann, wenn es um Java 8.

+0

Vielen Dank für die Lösung. Das ist der Standard, den ich wählen würde, wenn es keine bessere Lösung gäbe. Ich habe mich gefragt, ob es einen Weg gibt (vielleicht mit neuen Java 8 Stream-Techniken), um den Weg mit weniger Code auf elegante Weise zu bekommen. Übrigens: Sie müssen die Erstellungszeit nicht vergleichen, Sie können nur die Dateinamen vergleichen. –

+0

Ich bin mir nicht sicher, dass es schneller sein wird. Denn was DirectoryStream implementiert, ist Iterator. Wir können Consumer nur auf Iterator ausführen. Um es wirklich zu streamen, müssen wir es in Sammlung umwandeln. Also hier ist eine ziemlich hässliche Java-8-Version, aber ich ding nichts besseres kann daraus entstehen. –

+0

Vielleicht 'stream.forEach (list :: add)' vereitelt den Zweck der Verwendung eines _stream_; 'DirectoryStream' könnte ein richtiger Java 8' Stream' sein :-( –

1

Ich werde argumentieren, dass, da DirectoryStream nicht wirklich einen Java-8-Stream zur Verfügung stellt, auf die einfache alte File API zurückgreifen kann eine einfachere Lösung bieten. Zum Beispiel das folgende Programm:

public class MostRecentFile { 
    public static void main(String[] args) throws IOException { 
     Path dir = Paths.get(args[0]); 
     String regex = args[1]; 
     Arrays.stream(dir.toFile().listFiles(fn -> fn.getName().matches(regex))).sorted((f1, f2) -> { 
        try { 
         FileTime c2 = Files.readAttributes(f2.toPath(), 
          BasicFileAttributes.class).creationTime(); 
         FileTime c1 = Files.readAttributes(f1.toPath(), 
          BasicFileAttributes.class).creationTime(); 
         return c2.compareTo(c1); 
        } catch (IOException e) { 
         throw new RuntimeException(e); 
        } 
       } 
      ).findFirst().ifPresent(f -> System.out.println("found: " + f.getName())); 
    } 
} 

richtig druckt die neueste .txt Datei zuerst Argument (sagen wir) /tmp/files und zweite Argument .*txt (Anmerkung: Es ist ein regulärer Ausdruck, kein glob).

found: 6.txt 

(Das Verzeichnis enthält diese Dateien: 1 2 3.txt 5.txt 6.txt).