tutorials.de Buch-Aktion 05/2012
Like Tree3Danke
  • 1 Beitrag von Technoblade
  • 1 Beitrag von SE
  • 1 Beitrag von SE
ERLEDIGT
JA
ANTWORTEN
13
ZUGRIFFE
1396
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Hallo Miteinander

    Ich habe ein Problem und komme einfach nicht mehr weiter...


    Was das Programm tun soll:
    Das Programm soll sämtliche Subverzeichnisse durchstöbern und alle Dateien - ausser die 2 neusten - in den Verzeichnissen löschen.

    Mein Problem:
    Durch ein paar Foren und sonstige Internetseiten entdeckte ich die Klasse File.
    Mit dieser habe ich es auch geschafft, alle Unterverzeichnisse und auch die darin enthaltenen Dateien rekursiv aufzustöbern und auch bis auf die neuste zu löschen. So weit so gut.
    Der Haken an der Sache ist jedoch, dass jeweils die 2 neusten Dateien erhalten bleiben sollen.


    Ich habe es mal so probiert:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    public class Main
    {
        public static File file = new File("C:/Tests");
        
        public static void main(String[] args)
        {
            myMethod(file);
        }
        
        public static void myMethod(File directory)
        {
            File[] files = directory.listFiles();
            if(files!=null)
            {
                for(int i=0; i<files.length; i++)
                {
                    if(files[i].isDirectory()==true)
                    {
                        myMethod(files[i]);
                    }
                    else
                    {
    //                  files = directory.listFiles(); // wenn ich die Liste aktualisiere, kriege ich mit der Zeit einen "Index out of bounds"
                        for(File file : files)
                        {
                            files = directory.listFiles();
                            if(file.lastModified()<files[i].lastModified() && files.length>2) //Wenn die letzte modifizierte Zeit kleiner (also älter) UND mehr als 2 Dateien vorhanden sind, löschen - was jedoch nicht zu funktionieren scheint...
                                file.delete();
                        }
                    }
                }
            }
            else
                System.out.println("Keene Berechtigung...");
        }
     
    }

    Ich habe das Gefühl, dass die "Liste" sich nicht aktualisiert, wenn eine Datei darin gelöscht wird.
    So dachte ich mir, dass ich sie einfach aktualisieren kann (mit dem auskommentierten Befehl).
    HA! Falsch gedacht.
    Wenn ich den Befehl aufrufe, dann gibt es mitten im Ablauf einen "Index out of bounds" Error und das Programm macht auch nicht gerade das, was ich von ihm erwarte.


    Ich habe es hunderte mal gedreht und gewendet, ohne Erfolg.
    Ich hoffe, ihr könnt mir helfen :s
     

  2. #2
    Technoblade Technoblade ist offline Mitglied Gold
    Registriert seit
    Feb 2009
    Beiträge
    193
    Ich würde einen anderen Ansatz wählen. Ich würde es bei der einer Schleife belassen, und Variablen für zwei Files erstellen. In die packt man dann die beiden neusten Files die man bisher gefunden hat. Findet man dann ein noch neueres löscht man das ältere der beiden gesicherten Files und merkt sich das neuere. Reicht dir die Beschreibung oder soll hilft dir Quelltext mehr?
    PsychedelicSpark bedankt sich. 

  3. #3
    klein-odd klein-odd ist offline Mitglied Silber
    Registriert seit
    Feb 2007
    Beiträge
    52
    ... und ich hätte den Scan-vorgang mit

    File[] files = directory.listFiles();

    immerwieder unternommen, bis das Verzeichnis leer ist.
    Ungefähr so :


    File[] files = directory.listFiles();
    int anzahl = files.length;
    if(anzahl > 0)
    {//man nehme eine Datei, z.B.
    // File file = files[0];
    //gibt eventuell einen Warnhinweis aus:
    //JOptionPane.showMessageDialog(null,"Datei :\n"+file.getName()+"\nwird gelöscht","bereit zum Löschen",2,null);
    //die Datei wird gelöscht:
    // file.delete();
    //man scanne das Verzeichnis erneut:
    //files = directory.listFiles();
    //und prüft die Länge des Array :
    anzahl = files.length;
    und so weiter ...
    }
    else
    {
    //jetzt ist das Verzeichnis leer
    }

    Entschguldige, dass meine Tipperei nicht java-formatiert ist, ich weiss nicht, wie man dies hier tut

    Nach Wunsch kann ich es mit Eclipse versuchen.
    Es gibt bestimmt noch viele anderen Wege.
    Das Auflisten der Dateien ist mit moderner Hardware nicht besonders Speicherinstensiv, deswegen wurde ich die Lösung als modern ansehen, Gegenstimmen sind willkommen.
     

  4. #4
    Avatar von javaDeveloper2011
    javaDeveloper2011 javaDeveloper2011 ist offline Mitglied Brokat
    Registriert seit
    Feb 2011
    Beiträge
    443
    Blog-Einträge
    5
    Hi,

    @klein-odd
    Java-Code kann man so posten:
    [/JAVA] (NACH den Code)
    [JAVA] (VOR dem Code)

    sieht dann z.B. so aus:
    Code java:
    1
    
    System.out.println("How to post Java-Code");

    Gruß
     

  5. #5
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Hallo Leute.

    Ich habe es nun endlich geschafft, diese Aufgabe zu meistern.
    Ein dickes Dankeschön an Technoblade. Der Ansatz mit den 2 Puffer Dateien hat mir sehr geholfen


    Nun habe ich aber ein neues Problem...
    Mein Chef meinte, dass man in der Lage sein sollte, den"Startpfad" selbst anzugeben und das als Parameter.
    Also im Stil von java -jar DeleteFiles.jar _"C:/DB Backups"
    Gesagt, getan. Ich habe den Code umgeschrieben, sodass es eigentlich funktionieren müsste, aber jedes mal wenn ich das Programm per Konsole mit dem Parameter starte, scheint mein Programm keine Berechtigung zu haben, irgendwas in den Verzeichnissen zu tun.
    Wenn ich es mit Eclipse kompiliere und starte, hat er jedoch überhaupt keine Probleme und tut das, was man von ihm verlangt.

    Wie kann das sein?
    Wenn es an einer Sicherheitsvorkehrung des OS liegt (Win XP Pro), was kann man tun, um dem Programm die benötigte Berechtigung zu erteilen?

    _________________________________________________________________________________________

    EDIT: Wenn ich den Pfad statisch im Code angebe und die JAR mit einem Doppelklick oder auch per Konsole ausführe, gibt es auch keine Probleme.

    Hier noch ein kleiner Code-Schnipsel, wie ich das mit dem Parameter mache:
    Code java:
    1
    2
    3
    4
    5
    
    public static void main(String[] args)
        {   
            File file = new File(args[0]);      
            myMethod(file);
        }
    Die JAR rufe ich dann in der Konsole mit java -jar DeleteFiles.jar _"C:/Tests" auf.


    Gruss
    PsychedelicSpark
    Geändert von PsychedelicSpark (03.06.11 um 15:45 Uhr)
     

  6. #6
    Technoblade Technoblade ist offline Mitglied Gold
    Registriert seit
    Feb 2009
    Beiträge
    193
    Lass dir doch mal mit System.out.println(args[0]) ausgeben was von deiner Eingabe auf der Konsole auch im Programm an kommt.
     

  7. #7
    SE Tutorials.de Gastzugang
    Blöd Frage : Wozu der UNDERSCORE ?
    PsychedelicSpark bedankt sich. 

  8. #8
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Jjjjepp... Habe es auch gerade eben gemerkt i

    Ich dachte eben, dass man entweder ein - oder _ schreiben muss, wenn man einen Parameter mitgeben will.

    Nun ja.. scheint in dem Fall nicht so zu sein


    Vielen Dank an alle
    So kann ich das Programm ja auch beruhigt an den Chef aushändigen Xd
     

  9. #9
    SE Tutorials.de Gastzugang
    Achso ... die Parameter-Geschichte

    Dazu sei dir folgendes gesagt

    Ein Programm *auch eine Java-Applikation* kann nach bestimmten Parametern verlangen. Wenn das Programm dies tut gibt es in aller Regel auch vor WIE man diese zu übergeben hat. Es haben sich im Laufe der Zeit die Standards etabliert das man gewöhnlich vor sog. Switches folgende Zeichen setzt : einen einfachen Bindestrich (-) , zwei direkt aufeinander folgende Bindestriche (--) , einen Slash (/) oder garnichts.
    Dann trennt man die Switches von den Parameter-Werten meistens mit Leerzeichen oder einem =-Zeichen ...
    Wenn in einem Wert ein Leerzeichen enthalten ist ... dieser Wert aber als ein zusammenhängender Parameter übergeben werden soll muss in Abhängigkeit zum Interpreter die signalisiert werden. Zur Zeit hat sich der Standard etabliert das man solche Paramter in doppelte Anführungszeichen setzt ("WERT").

    WIE genau man DEINER Applikation aber nun die Parameter übergeben muss das legst du selbst innerhalb der
    Code java:
    1
    
    public static void main(String[] args)
    fast. In Java erhältst du sämtliche übergebenen Parameter nach dem Parameter deiner Klasse an Java selbst als String-Array. Dies weicht von Sprache zu Sprache stark ab.
    Mit diesen Strings kannst du nun sämtliche String-Vergleiche anstellen die du willst. Du kannst zum Beispiel in einem foreach durch alle Parameter gehen und prüfen ob sie das von dir geforderte Format aufweisen *z.B. mit Slash für Toggle-Switches ... einfachen Bindestrich für restliche Parameter ... Werte müssen mit "=" verknüpft sein ... und so weiter* und auch Parsen falls du z.B. einen numerischen Wert brauchst / verlangst.
    Da du selbst aber deine main-Methode so aufgebaut hast das du nach dem reinen Pfad verlangst musst du ihn dann auch so übergeben.

    Ich weis ... klingt kompliziert und unlogisch ... aber genau das ist es auch ... denn jeder Programmierer macht sein eigenes Ding. Es gibt zwar wie auch in Java Konventionen die eine Vorgabe darstellen nach der man sich richten SOLLTE um es wenigstens innerhalb der selben Sprache gleich zu halten ... aber für soetwas Sprachübergreifendes ist das ganz schlicht zu komplex.
    PsychedelicSpark bedankt sich. 

  10. #10
    klein-odd klein-odd ist offline Mitglied Silber
    Registriert seit
    Feb 2007
    Beiträge
    52
    Ich danke JavaDeveloper für den Tipp.
    Ich habe mit den Löschprozedurn experimentiert aber momentan kann
    ich keinen sicheren Code zeigen.
    Es haben sich Probleme ergeben.

    JAVA löscht mur leere Verzeichnisse

    Gut finde ich, dass der Problemsteller die Angelegenheit erledigt hat, oder irre ich ?
    Ich grüsse allle, Alexander
     

  11. #11
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Ja, das Problem hat sich erledigt.
    Es ist zwar bislang nicht die Code- und Leistungs-sparendste Lösung, aber immerhin tut das Programm schon mal genau das, was es auch tun soll. Nicht mehr und auch nicht weniger.

    Falls es dich interessiert, wie ich es gelöst habe, hier der Code:
    Und bitte: bewerft mich nicht mit Steinen, wenn ihr seht, wie viel unnötigen Code ich da reingebastelt habe

    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.Vector;
     
     
    public class Main
    {   
        public static boolean noFurtherDirectories;
     
        public static void main(String[] args)
        {
            File file = new File(args[0]);      
            myMethod(file);
        }
        
        public static void myMethod(File directory)
        {   
            File[] files = directory.listFiles();
            
            File fileOne = new File("C:/Tests"); // Puffer-File 1
            File fileTwo = new File("C:/Tests"); // Puffer-File 2
            
            Vector<File> vec = new Vector<File>();
            
            // Eine Datei oder ein Verzeichnis vorhanden/zugreifbar?
            if(files!=null)
            {   
                // Beim letzten Verzeichnis des Verzeichnisbaums angelangt?
                for(File file : files)
                {
                    files = directory.listFiles();
                    
                    if(file.isDirectory()==false)
                        noFurtherDirectories=true;
                    else
                        noFurtherDirectories=false;
                }
                
                // Jede Datei im Verzeichnis überprüfen
                for(File file : files)
                {
                    files = directory.listFiles();
                    
                    // Ist es ein Verzeichnis?
                    if(file.isDirectory()==true)
                    {
                        // Neuste Datei des vorherigen Verzeichnisses ermitteln
                        for(int i=0; i<vec.size(); i++)
                        {
                            if(vec.get(i).lastModified()>fileOne.lastModified())
                                fileOne = vec.get(i);
                        }
                        // 2. neuste Datei des vorherigen Verzeichnisses ermitteln
                        for(int i=0; i<vec.size(); i++)
                        {
                            if(vec.get(i).lastModified()>fileTwo.lastModified() && vec.get(i).lastModified()<fileOne.lastModified())
                                fileTwo = vec.get(i);
                        }
                        // Alle Dateien aus Puffer-Liste löschen
                        vec.removeAllElements();
                        // Pfad des oberen Verzeichnisses im Verzeichnisbaum ermitteln
                        File parent = new File(file.getParent());
                        // Aufruf der Lösch-Methode
                        delete(parent, fileOne, fileTwo);
                        // Die Methode ruft sich selber auf
                        myMethod(file);
                    }
                    else // Ist es eine Datei?
                        vec.add(file); // Der Puffer-Liste die momentane im Fokus stehende Datei hinzufügen
                }
                
                // Wenn kein Unterverzeichnis mehr vorhanden
                if(noFurtherDirectories == true)
                {
                    for(File file : files)
                    {
                        for(int i=0; i<vec.size(); i++)
                        {
                            if(vec.get(i).lastModified()>fileOne.lastModified())
                                fileOne = vec.get(i);
                        }
                        for(int i=0; i<vec.size(); i++)
                        {
                            if(vec.get(i).lastModified()>fileTwo.lastModified() && vec.get(i).lastModified()<fileOne.lastModified())
                                fileTwo = vec.get(i);
                        }
                        
                        vec.removeAllElements();
                        
                        //Aufruf Lösch-Methode, jedoch mit dem Pfad des momentanen Verzeichnisses
                        delete(directory, fileOne, fileTwo);
                    }
                }
            }
            else // Nicht lesbar oder keine zugriffsrechte?
                System.out.println("Keine Berechtigung...");
            
        }
        
        // Lösch-Methode
        public static void delete(File directory, File fileOne, File fileTwo)
        {
            File[] files = directory.listFiles();
            
            if(files!=null)
            {   
                for(File file : files)
                {
                    files = directory.listFiles();
                    
                    // Ist es eine Datei? (Kein Verzeichnis)
                    if(file.isFile())
                    {
                        // Wenn nicht die neuste oder 2. neuste Datei
                        if(file.equals(fileOne)==false && file.equals(fileTwo)==false)
                            file.delete(); //löschen
                    }
                }
            }
            else
                System.out.println("Keine Berechtigung...");
        }
     
    }

    Momentan bin ich aber noch an einer "besseren" und auch schöneren Lösung dran, bei der man als zusätzlicher Parameter noch mitgeben kann, wie viele der neusten Dateien behalten werden sollen.
     

  12. #12
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Hallo Zusammen

    Nach langen Testphasen, kam das Programm nun zum Einsatz.
    Es ergab sich jedoch ein Problem: Die Abfragen scheinen nur für gewisse Datentypen zu funktionieren.
    Alles andere löscht es gnadenlos. Egal wie alt oder wie viele Dateien insgesamt da sind.

    Das skurrile ist, dass das Programm beim Windows XP genau so funktioniert, wie man es von ihm erwartet.

    Beim Windows Server 2008 R2 und (wie ich nachher durch einen Test bestätigen konnte) Windows 7 funktioniert das Programm nur bei gewissen Datentypen...
    Ich habe ein paar Datentypen getestet und richtig funktionieren tut es bei BackUp Files und Bitmap Dateien.
    Nicht zu funktionieren scheinen die Typen: txt, rtf, log, jpeg, png, zip und wahrscheinlich noch viele mehr.


    Wie zum Teufel kann das sein?!

    _______________________________________________________________________________________

    Ok, habe wahrscheinlich herausgefunden, wieso das bei Windoof 7 passiert.
    In Windoof 7 gibt es bei vielen Dateien kein "Zuletzt geändert"-Attribut. Nur ein "Erstellt am".
    Darum gibt mir die File.lastModiefied() Methode immer "0" zurück.

    So habe ich nun nach einer Methode gesucht, die das Erstellungsdatum ermittelt, jedoch vergebens.

    Gibt es eine intelligente Alternative zur lastModified() Methode?
    Irgend etwas, dass die Erstellungszeit zurück gibt?
    Geändert von PsychedelicSpark (22.06.11 um 11:57 Uhr)
     

  13. #13
    Technoblade Technoblade ist offline Mitglied Gold
    Registriert seit
    Feb 2009
    Beiträge
    193
    Ich habe mal ein wenig gegoogelt. Allerdings nur eine Lösung in C++ für Windows gefunden. Die könntest du über eine native Methode in dein Programm einbauen. Das ist allerdings ein wenig schwirieger und man muss dafür zumindest ein bisschen C++ können. Solltest du das nicht können müsste dir dein Chef evtl. unter die Arme greifen.
    Ansonsten würde ich auch wohl den C++ teil übernehmen, das wäre eine schöne Übung für mich. Allerdings ist es ja deine Aufgabe.
     

  14. #14
    PsychedelicSpark PsychedelicSpark ist offline Mitglied
    Registriert seit
    Feb 2011
    Beiträge
    14
    Hatte die Seite die ganze Zeit als einen Tab im Opera und bin zufällig wieder drüber gestolpert

    Also, das Thema ist gegessen.
    Ich habe es einfach mit PowerShell realisiert. 10x einfacher, 10x Code-sparender (auch wenn die Syntax etwas gewöhnungsbedürftig ist..)

    Wen es interessiert, hier die Lösung in PowerShell (mit Übergabeparametern 'Pfad' und 'Anzahl zu behaltende Dateien'):
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    $startDirectory = $args[0]
    $numberOfSaves = $args[1]
     
    cd $startDirectory
      
    ls -recurse | foreach($_){
      if(!$_.PSIscontainer){
        ls *.* | ? {!$_.psiscontainer} | sort LastWriteTime -desc | select -skip([int]$numberOfSaves) | del
      }
      if($_.PSIscontainer){
        ls $_.pspath | ? {!$_.psiscontainer} | sort LastWriteTime -desc | select -skip([int]$numberOfSaves) | del
      }
    }
     

Ähnliche Themen

  1. [MySQL] Alte Constraints löschen
    Von Tim Bureck im Forum Relationale Datenbanksysteme
    Antworten: 1
    Letzter Beitrag: 26.07.10, 15:12
  2. alte Datensätze löschen
    Von valkuere im Forum PHP
    Antworten: 3
    Letzter Beitrag: 06.10.06, 13:06
  3. alte beiträge (1 mon.) löschen : cronjob
    Von PersonalDemon im Forum PHP
    Antworten: 5
    Letzter Beitrag: 07.03.05, 15:46
  4. Bei TSM alte log Dateien löschen
    Von blauemurmel im Forum Sonstige Sprachen
    Antworten: 0
    Letzter Beitrag: 06.04.04, 14:46
  5. Alte Einträge in Tabelle löschen
    Von sevi im Forum Relationale Datenbanksysteme
    Antworten: 1
    Letzter Beitrag: 10.03.04, 12:48