Methoden Dateien älter als 30 Tage?

lam_tr

Top Contributor
Hallo zusammen,

gibt es einen Weg, Dateien die nicht älter als 30 Tage zu bekommen?

Momentan ist es so dass ich über das Netzlaufwerk Verzeichnisse hole. Leider sind da mehrere 10.000 Dateien in viele Verzeichnissen. Um nur die aktuellen Dateien zu holen, möchte ich die Dateiliste filtern.

1. Frage: Gibt es einen Weg performanter vorzugehen. Alle Dateien im Filer durchiterieren und rekursiv ist nicht so sinnvoll oder?

2. Frage: Wie bekomme ich nur die aktuellen Dateien von max 30 tage?
Code:
    if ( !FileUtils.isFileOlder(file, DateTime.now().minusDays(30).toDate()) ) {
       files.add(file);
    }

Hiermit geht das nicht.

Viele Grüße
lam
 
1. Frage: Gibt es einen Weg performanter vorzugehen. Alle Dateien im Filer durchiterieren und rekursiv ist nicht so sinnvoll oder?
Mir würde spontan auch keine andere Lösung einfallen. Auch eine Framework Methode würde es nicht anders machen, nur vielleicht performanter.

2. Frage: Wie bekomme ich nur die aktuellen Dateien von max 30 tage?
Hast du dir oben schon selber beantwortet. Über alles iterieren und prüfen.

Code:
    if ( !FileUtils.isFileOlder(file, DateTime.now().minusDays(30).toDate()) ) {
Tipp 1: Anstatt für jede Datei die Datumsgrenze extra zu berechnen würde ich dies 1x am Anfang machen.
Tipp 2: File bietet die Methode "lastModified" an. Diese liefert dir einen long zurück, welcher der letzten Bearbeitungszeit entspricht. Hier mit long zu rechnen und zu vergleichen ist auch schon performanter.
 
Vielen Dank für die schnelle Antwort. das mit dem lastmodified habe ich schon in einigen Tutorials schon gesehen, aber irgendwie hatte es auch nicht wirklich bei mir funktioniert. Das erschwert sogar das debuggen.

Also den folgenden Code habe ich schon getestet.

Code:
long diff =newDate().getTime()- file.lastModified();
if(diff > x *24*60*60*1000){
}

Ich bin ehrlich gesagt etwas verzweifelt.

Ich habe sogar versucht, das Jahr zu nehmen und alle Files die vom lastModified deren Jahr rauszuschreiben.

Oder allgemein habe ich den oberen Code noch nicht verstanden.

Viele Grüße
lam
 
...aber irgendwie hatte es auch nicht wirklich bei mir funktioniert.
Was bedeutet dann "nicht wirklich funktioniert"? Laufzeitfehler, falsches Ergebnis (zu viel oder zu wenig gefiltert)?

Das erschwert sogar das debuggen.
Weil? Mit der passenden IDE kannst du während dem Debuggen diese Zahlen in ein Date umwandeln lassen um deren Richtigkeit zu testen.
Auch sagt ja keiner etwas wenn für Logausgaben der Wert eben in ein Date umgewandelt wird. Nur für die produktive Laufzeit sollte man solche Umwandlungen dann eben auskommentieren oder ähnliches.

Code:
long diff =newDate().getTime()- file.lastModified();
if(diff > x *24*60*60*1000){
}
Oder allgemein habe ich den oberen Code noch nicht verstanden.
Der Code berechnet sich zuerst die Differenz zwischen heutigen Datum/Uhrzeit und der letzten Bearbeitungszeit der Datei.
Dann wird geschaut ob dieser Wert größer ist als der gewünscht Grenzwert. In diesem Fall ist der Grenzwert x Tage.
24 Stunden * 60 Minuten * 60 Sekunden * 1000 Millisekunden * x Tage
 
Zuletzt bearbeitet:
Schön dann hat der Filter nicht richtig funktioniert, aber so ohne Code lässt sichs auch schwer sagen was der Fehler war.
Probiere es nochmal umzusetzen und sollte das Problem weiterhin auftauchen, dann poste auch etwas von deinem Code.
 
Das Problem kann evtl. sein, dass x bei dir ein int ist, daher rechnet er bei dir alles über int aus und dabei bekommst du einen Überlauf. Und diff ist dann halt größer ... Also ((long)x) sollte das Problem ggf. lösen.
 
Ich habe das auch eben einmal ausgetestet - das ist tatsächlich das Problem. bei 30 Tagen bekommst Du als Integer-Wert nach der Berechnung -1702967296 raus. Und jede Differenz ist dann natürlich größer so dass alle Files ausgegeben werden.
Code:
if(diff > ((long)x) *24*60*60*1000){
sollte das Problem lösen - das hat es zumindest bei mir.
 
kann man nicht einfach die list Methode der Klasse File mit einem FileFilter verwenden?

Java:
File directory = new File("Pfad zu meinem verzeichnis");
     File[] files = directory.listFiles(new FileFilter() {
       
       @Override
       public boolean accept(File file) {

         boolean accept = false;
         long actualTime = System.currentTimeMillis();
         long fileTime = file.lastModified();
         short daysBetween = (short)(((((actualTime - fileTime) / 1000) / 60) / 60) / 24);
         
         if(daysBetween <= 30) {
           
           accept = true;
         }
         
         return accept;
       }
     });
 
Jo, das wäre wohl auch die elegantere Version. Diese Anregung habe ich dann auch einmal aufgenommen und ein kleines Refactoring vorgenommen.

Code:
// In Klasse selbst
private final static long MILISECONDS_PER_DAY = 1000 * 60 * 60 * 24;

// In einer Funktion, wo es benötigt wird.
File directory = new File("Pfad zu meinem verzeichnis");
File[] files = directory.listFiles(file -> (System.currentTimeMillis() - file.lastModified()) / MILISECONDS_PER_DAY <= 30);

Eigentlich nur Deine Funktion vereinfacht:
- viele Klammern und den Cast braucht man nicht in der Berechnung.
- Magic Numbers werden durch Konstante ersetzt.
- Die beiden Funktionsaufrufe kann man direkt in die Berechnung setzen.
- Die Accept Variable braucht man nicht, da die ja nur direkt per return zurück gegeben wird.
- Vorletzte Änderung ist danach dann auf if (bedingung) return true; else return false; das return bedingung; zu machen.
- Und die letzte Änderung ist dann, die Funktion, die ausschließlich ein return Statement hat, als Lambda Ausdruck zu schreiben.

Das aber nur so am Rande als eine Möglichkeit. Deine Idee mit genau so einem Filter ist goldrichtig!
 
Eigentlich nur Deine Funktion vereinfacht:
- viele Klammern und den Cast braucht man nicht in der Berechnung.
- Magic Numbers werden durch Konstante ersetzt.
- Die beiden Funktionsaufrufe kann man direkt in die Berechnung setzen.
- Die Accept Variable braucht man nicht, da die ja nur direkt per return zurück gegeben wird.
- Vorletzte Änderung ist danach dann auf if (bedingung) return true; else return false; das return bedingung; zu machen.
- Und die letzte Änderung ist dann, die Funktion, die ausschließlich ein return Statement hat, als Lambda Ausdruck zu schreiben.

Das aber nur so am Rande als eine Möglichkeit. Deine Idee mit genau so einem Filter ist goldrichtig!
Die Klammern habe ich nur für mehr übersicht da.
Ich versuche immer den kleinst möglichen Datentypen zu verwendenin der Hoffnung, dass ich etwas speicher spare. Und Lambda ist hässlich 😛
 
Zuletzt bearbeitet von einem Moderator:
Nunja - dieses Speicher sparen um jeden Preis haut nur leider nicht wirklich hin, denn die CPUs heute arbeiten mit mind. 32 Bit. Drunter dürfte es wohl kaum noch geben, oder gibt es Java auf irgendwelchen 16 Bit Plattformen?
Somit hast Du zwar im Code die Begrenzung aber der Compiler ändert das dann, damit es schnell und zügig abgearbeitet werden kann. Aber ansonsten ist das Vorgehen generell gut und richtig - man sollte immer den passenden Datentyp wählen - unabhängig was für Optimierungen dann im Hintergrund evtl. laufen oder nicht laufen.

Und was die Lambdas angeht, hast Du da teilweise nicht Unrecht. Ich liebe an IntelliJ, dass es automatisch hin und zurück wandeln kann und dann schaue ich mir gerne mal an, wie es aussieht und wie gut es lesbar ist. Und oft verliert der Lambda Ausdruck dann. (Dies war aber einer der Fälle, bei dem ich es ok und lesbar fand. Aber das ist natürlich ein rein subjektiver Eindruck von mir!)
 

Neue Themen


Zurück
Oben