Announcement

Collapse
No announcement yet.

Snippet: Suchen nach Dateien

Collapse
This is a sticky topic.
X
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Snippet: Suchen nach Dateien

    Suchen nach Dateien
    Sicherlich eine der ersten Anforderungen an eine Programmiersprache ist
    es, nach Verzeichnissen und Dateien suchen zu können.
    Java macht es dem Entwickler ziemlich einfach. Die Klasse File bietet
    schon weitreichende Möglichkeiten, nach Verzeichnissen und Dateien
    suchen zu können. In anderen Umgebungen (WIN 32 API) ist allein dazu
    schon weit mehr Aufwand erforderlich.
    Jedoch soll hier eine Klasse implementiert werden, die die Möglichkeiten
    der Klasse File etwas erweitert. Es soll die Möglichkeit geben,

    - die Suche auf bestimmte Dateierweiterungen zu beschränken
    - Unterverzeichnisse sollen mit durchsucht werden
    - das Dateidatum soll berücksichtigt werden
    - die Ergebnisliste soll sortiert werden
    - über einen Listener wird über die Sucherfolge informiert

    Dazu erstellen wir eine neue Klasse und nehmen ein Enum sowie diverse
    Felder als Klassenvariablen auf
    [highlight=java]
    public class GFileSearch
    {
    public enum Date_Compare
    {
    DATE_BEFORE,
    DATE_AFTER,
    DATE_EQUAL
    };
    private String path;
    private ArrayList<File> ergebnisListe;
    private Set<String> extension;
    private boolean extCaseSensitiv;
    private boolean directorys;
    private boolean unterverzeichnisse;
    private boolean sort;
    private Comparator<File> sortFileComparator;
    private Date datum;
    private Date_Compare datumcompare;
    private PropertyChangeSupport propertySupport=new PropertyChangeSupport(this);
    private boolean interrupted=false;
    [/highlight]
    Das Enum "Date_Compare" dient zur Bestimmung, ob bei Vorgabe eines
    Datums das Datum der Datei übereinstimmen muss oder davor oder
    dahinter liegen soll

    Der String "path" nimmt das Startverzeichnis, ab dem eine Suche
    erfolgen soll, auf

    Die ArrayList "ergebnisliste" enthält nach erfolgter Suche das
    Suchergebnis. Sie ist kumulativ. D.h. eine Suche mit der
    gleichen Instanz der Klasse ohne eine Löschung der Liste, fügt
    der Liste die neunen Ergebnisse hinzu.

    Das Set "extension" enthält eine Liste von Dateiextension nach
    denen gesucht wird.

    Der boolean "extCaseSensitiv" zeigt an,ob bei der Suche mit denen in
    der Liste "extension" angegeben Extensionen die Groß-/Kleinschreibung
    berücksichtigt wird.

    Der boolean "directorys" zeigt an,ob gefundene Verzeichnisse mit in
    die Ergebnisliste aufgenommen werden.

    Der boolean "unterverzeichnisse" zeigt an, ob Unterverzeichnisse
    rekurisiv mit durchsucht werden

    Der boolean "sort" zeigt an, ob die Ergebnisliste sortiert werden
    soll.

    Der Comparator "sortFileComparator" bestimmt, mit welchen Comparator
    die Sortierung erfolgt.

    Das Date "Datum" wird für den Vergleich mit dem Dateidatum herangezogen.

    Für einen Datumsvergleich wird dann mit "datumcompare" festgelegt, wie
    der Vergleich durchgeführt wird.

    Um während der Suche seitens des aufrufenden Programmes anzeigen zu
    können, welche Verzeichnisse und Dateinen gerade gefunden werden,
    wird das Listenerkonzept von Java genutzt. Mit "propertySupport"
    wird es ermöglicht, dass sich Listener anmelden können und informiert
    werden.

    Die laufende Suche kann mit dem Setzen des boolean "interrupted"
    abgebrochen werden.

    Im Konstruktor werden die Vorbelegungen gesetzt:
    [highlight=java]
    public GFileSearch()
    {
    this.path="";
    this.ergebnisListe=new ArrayList<File>();
    this.extension=new HashSet<String>();
    this.extCaseSensitiv=false;
    this.directorys=false;
    this.unterverzeichnisse=false;
    this.sort=false;
    this.sortFileComparator=new GFileComparator();
    this.datum=null;
    }
    [/highlight]

    Die Getter und Setter und Hilfsmethoden für die
    Klassenvariablen:
    [highlight=java]
    public String getPath()
    {
    return path;
    }
    public void setPath(String path)
    {
    this.path=path;
    }
    public ArrayList<File> getErgebnisListe()
    {
    return ergebnisListe;
    }
    public void clearErgebnisListe()
    {
    ergebnisListe.clear();
    }
    [/highlight]

    Für mehrere Suchen in einer Instanz muss - wenn die Ergebnisse nicht
    kumuliert werden sollen - die Ergebnisliste gelöscht werden
    Zuletzt editiert von Christian Marquardt; 30.01.2011, 22:44.
    Christian

  • #2
    [highlight=java]
    public Set<String> getExtension()
    {
    return extension;
    }
    public void setExtension(String... extension)
    {
    for(String string:extension)
    {
    string=string.replaceAll(STEHT_IM_DOWNLOAD);
    string=string.replaceAll(STEHT_IM_DOWNLOAD);
    string=string.replace(STEHT_IM_DOWNLOAD));
    this.extension.add(string);
    }
    }
    public void clearExtension()
    {
    this.extension.clear();
    }
    [/highlight]
    Normalerweise entsprechen die Setter auch dem Datentyp der Variable. Das
    ist bei den Extension ein HashSet. Um nicht wegen der Vorgabe einer Extension
    wie *.bmp ein HashSet anlegen zu müssen wurde die o.a. Möglichkeit gewählt.
    So kann das mit einer beliebigen Anzahl von Parametern wie folgt
    aufgerufen werden:
    setextension("*.bmp")
    setextension("*.bmp","*.jpg","*.tif")
    [highlight=java]
    public boolean isExtCaseSensitiv()
    {
    return extCaseSensitiv;
    }
    public void setExtCaseSensitiv(boolean extCaseSensitiv)
    {
    this.extCaseSensitiv=extCaseSensitiv;
    }
    public boolean isDirectorys()
    {
    return directorys;
    }
    public void setDirectorys(boolean directorys)
    {
    this.directorys=directorys;
    }
    public boolean isUnterverzeichnisse()
    {
    return unterverzeichnisse;
    }
    public void setUnterverzeichnisse(boolean unterverzeichnisse)
    {
    this.unterverzeichnisse=unterverzeichnisse;
    }
    public boolean isSort()
    {
    return sort;
    }
    public void setSort(boolean sort)
    {
    this.sort=sort;
    }
    public Comparator<File> getSortFileComparator()
    {
    return sortFileComparator;
    }
    public void setSortFileComparator(Comparator<File> sortFileComparator)
    {
    if(sortFileComparator!=null)
    {
    this.sort=true;
    this.sortFileComparator=sortFileComparator;
    }
    }
    public Date getDatum()
    {
    return datum;
    }
    public void setDatum(String datum,String format,Date_Compare compare) throws ParseException
    {
    SimpleDateFormat sdf=new SimpleDateFormat(format);
    Date dt=sdf.parse(datum);
    this.datum=clearTime(dt);
    this.datumcompare=compare;
    }
    public void setDatum(Date datum,Date_Compare com)
    {
    this.datum=clearTime(datum);
    this.datumcompare=com;
    }
    public void clearDatum()
    {
    this.datum=null;
    }
    [/highlight]
    Auch die Vorgabe des Datum wurde vereinfacht. Mit einer Methode kann eine Date
    Klasse vorgegeben werden. Mit einer weiteren ein Datum im Stringformat. Dazu
    ist dann die Vorgabe des Formates (siehe Klasse SimpleDateFormat) erforderlich.
    Beispiel:
    setDatum("01.01.2000","dd.MM.yyyy",Date_Compare.DA TE_AFTER)
    Zuletzt editiert von Christian Marquardt; 30.01.2011, 22:45.
    Christian

    Comment


    • #3
      [highlight=java]
      public void addGFileSearchPropertyChangeListener(PropertyChang eListener listener)
      {
      propertySupport.addPropertyChangeListener(listener );
      }
      public void removeGFileSearchPropertyChangeListener(PropertyCh angeListener listener)
      {
      propertySupport.removePropertyChangeListener(liste ner);
      }
      [/highlight]
      Wird ein Listener genutzt, so wird ein Change gefeuert derart:
      propertySupport.firePropertyChange("FILE","",NAME_ DER_DATEI);
      propertySupport.firePropertyChange("DIRECTORY","", NAME_DES_ORDNERS);
      [highlight=java]
      public void interruptSuche()
      {
      interrupted=true;
      }
      public void search()
      {
      if(path.isEmpty())
      {
      return;
      }
      if(extension.isEmpty())
      {
      extension.add(STEHT_IM_DOWNLOAD);
      }
      interrupted=false;
      rekursiveSuche(path);
      if(sort)
      {
      Collections.sort(ergebnisListe,sortFileComparator) ;
      }
      }
      private void rekursiveSuche(String path)
      {
      File f=new File(path);
      FilenameFilter filter=new FilenameFilterImpl();
      File[] erg=f.listFiles(filter);
      if(erg==null)
      {
      return;
      }
      for(int i=0;i<erg.length;i++)
      {
      if(interrupted)
      {
      ergebnisListe.clear();
      break;
      }
      if(erg[i].isDirectory()&&directorys)
      {
      ergebnisListe.add(erg[i]);
      }
      else
      {
      if(!erg[i].isDirectory())
      {
      propertySupport.firePropertyChange("FILE","",erg[i]);
      ergebnisListe.add(erg[i]);
      }
      }
      if(erg[i].isDirectory()&&unterverzeichnisse)
      {
      propertySupport.firePropertyChange("DIRECTORY","", erg[i]);
      rekursiveSuche(erg[i].getAbsolutePath());
      }
      }
      }
      private Date clearTime(Date datum)
      {
      if(datum==null)
      {
      return null;
      }
      GregorianCalendar cal=new GregorianCalendar();
      cal.setTime(datum);
      cal.set(Calendar.HOUR,0);
      cal.set(Calendar.MINUTE,0);
      cal.set(Calendar.SECOND,0);
      cal.set(Calendar.MILLISECOND,0);
      return cal.getTime();
      }
      [/highlight]
      "clearTime":Für den Datumsvergleich müssen die Zeitangaben ausgeblendet werden
      Zuletzt editiert von Christian Marquardt; 22.03.2011, 17:38.
      Christian

      Comment


      • #4
        [highlight=java]
        private class FilenameFilterImpl implements FilenameFilter
        {
        public FilenameFilterImpl()
        {
        }
        @Override
        public boolean accept(File dir,String name)
        {
        File ftest=new File(dir.getAbsolutePath()+"\\"+name);
        if(ftest.isDirectory())
        {
        return true;
        }
        boolean gefunden=false;
        for(String ext:extension)
        {
        Pattern p=null;
        if(extCaseSensitiv)
        {
        p=Pattern.compile(ext);
        }
        else
        {
        p=Pattern.compile(ext,Pattern.CASE_INSENSITIVE);
        }
        Matcher m=p.matcher(name);
        if(m.matches())
        {
        gefunden=true;
        break;
        }
        }
        if(!gefunden)
        {
        return false;
        }
        if(datum!=null)
        {
        Date filedate=clearTime(new Date(ftest.lastModified()));
        switch(datumcompare)
        {
        case DATE_BEFORE:
        if(filedate.after(datum))
        {
        return false;
        }
        break;
        case DATE_AFTER:
        if(filedate.before(datum))
        {
        return false;
        }
        break;
        case DATE_EQUAL:
        if(filedate.before(datum)||filedate.after(datum))
        {
        return false;
        }
        }
        }
        return true;
        }
        }
        }
        [/highlight]
        Die Klasse FilenameFilterImpl filtert die Extensions und - sofern vorgegeben
        das Dateidatum
        Zuletzt editiert von Christian Marquardt; 30.01.2011, 22:46.
        Christian

        Comment


        • #5
          Anbei die fertige Klasse

          GFileSearch.zip


          und die benötigte Comparatorklasse für eine Sortierung
          Korrekturen, Anmerkungen, Verbesserungen bitte per PN.



          Beispiel:
          [highlight=java]
          GFileSearch search=new GFileSearch();
          search.setPath("g:\\Incomming");
          search.setDirectorys(false);
          search.setUnterverzeichnisse(true);
          search.setDatum("01.09.2010","dd.MM.yyyy",GFileSea rch.Date_Compare.DATE_AFTER);
          search.addGFileSearchPropertyChangeListener(new PropertyChangeListener()
          {
          @Override
          public void propertyChange(PropertyChangeEvent evt)
          {
          System.out.println("---->"+evt.getNewValue());
          }
          });
          search.search();
          ArrayList<File> ss=search.getErgebnisListe();
          for(File file:ss)
          {
          System.out.println(file.getPath());
          }
          [/highlight]
          Zuletzt editiert von Christian Marquardt; 30.01.2011, 22:47.
          Christian

          Comment

          Working...
          X