IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

FileFilter générique type linux


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut FileFilter générique type linux
    Bonjour,

    Pour les besoins d'une application qui toune sous GNU/Linux, j'ai écrit une classe ArgFilter qui implémente java.io.FileFilter pour filtrer des noms de fichiers de la facon la plus générale qui soit.
    Je cherche à reproduire le même genre de filtre d'argument qu'offre la commande ls en linux : un filtre du genre *iMg*.nc

    J'ai un petit code qui à l'air de marcher.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    //////////////////////////////////////////////
      public class ArgFilter implements java.io.FileFilter {
     
        private String filter;
        private String[] splitFilter;
        private int nbPattern;
        private boolean allFiles;
     
        //------------------------------
        public ArgFilter(String arg) {
          filter = arg;
          allFiles = filter.equals("*.*") || filter.equals("*");
          splitFilter = filter.split("\\*");
          nbPattern = splitFilter.length;
        }
     
        //-----------------------------
        public boolean accept(File f) {
     
          // Return false if directory
          if (!f.isFile()) return false;
          // Return true if "*.*"
          if (allFiles) return true;
          String n = f.getName();
          // Return false if file length smaller than filter length
          if (n.length() < filter.length()) return false;
          String pattern = splitFilter[0];
          // Process first and last patterns in case they are not "*"
          if (pattern != null && !n.startsWith(pattern)) return false;
          if (!filter.endsWith("*") && !n.endsWith(splitFilter[nbPattern - 1])) return false;
          String subn;
          // Process other patterns
          int k = (pattern != null) ? pattern.length() : 0;
          for (int i = 1; i < nbPattern; i++) {
            pattern = splitFilter[i];
            if (pattern != null) {
              subn = n.substring(k);
              if (subn.contains(pattern)) k = subn.indexOf(pattern) + pattern.length();
              else return false;
            }
          }
          // Eventually return true
          return true;
        }
      }
    Que j'utilise de la façon suivante, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    File inputPath = new File("/lib/");
    File[] listFile = inputPath.listFiles(new ArgFilter("li*mca*"));
    for (File file : listFile) System.out.print(file.getName() + " ");
    Je le soumets simplement à vos critiques et commentaires. Est-ce la bonne façon de s'y prendre ? Comment l'améliorer ? Toutes remarques bienvenues !
    Merci d'avance
    Philippe.

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Pattern + Matcher ou comment utiliser les regex en java

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Merci Sinok !
    Pour le coup c'est moi qui suis bien pourrave ... je ne connaissais pas les regex, les matchers, etc.

    Merci pour ces liens, pas facile quand même d'apréhender les Regex !
    J'ai reécrit ma classe ArgFilter en utilisant simplement un String.matches() dans la méthode Filefilter.accept().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    public class ArgFilter implements FileFilter {
     
        private String pattern;
     
        //------------------------------
        public ArgFilter(String arg) {
          // Transform the argument into regex with reluctant quantifiers
          pattern = arg.replaceAll("\\*", "(\\.\\*\\?)");
          System.out.println(pattern);
        }
     
        //-----------------------------
        public boolean accept(File f) {
     
          // Return false if directory
          if (!f.isFile()) return false;
          // Return true if file name matche the pattern
          return f.getName().matches(pattern);
        }
      }
    Dans le constructeur je remplace tous les charactères * de l'argument par l'expression regulière (.*?) pour avoir le bon pattern.
    Ca a l'air de marcher. Sinok, c'est bien par là que tu voulais m'orienter ?
    J'utilise un Reluctant quantifier, mais j'ai du mal à comprendre ce qu'implique l'utilisation de l'un ou l'autre des quantifiers ...

    Encore merci. Philippe.

  4. #4
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    adiGuba a posté le source d'un FilenameFilter faisant ce que tu veux (ici), tu doit pouvoir l'adapter à un FileFilter .
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Ok, merci pour le lien, c'est exactement ce que je cherchais à faire. J'ai mal cherché sur le forum, je n'avais pas vu son post...
    Je suis bon pour un petit délestage.

    Mon code ressemble sensiblement à celui proposé par adiGuba, sauf que je ne tenais pas compte du métacharactère ?.

    Il utilise un Greedy quantifier là ou j'utilise un Reluctant qualifier. Je ne vois pas très bien ce que ça implique concrètement, l'explication de la javadoc et du tuto ne m'éclairent pas vraiment.

    Merci M. le Yam's ! Philippe.

    J'ai parlé un peu vite, j'ai une erreur à l'éxecution du code d'adiGuba
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 3
    \\Q\\E
       ^
    	at java.util.regex.Pattern.error(Unknown Source)
    	at java.util.regex.Pattern.compile(Unknown Source)
    	at java.util.regex.Pattern.<init>(Unknown Source)
    	at java.util.regex.Pattern.compile(Unknown Source)
    	at java.lang.String.replaceAll(Unknown Source)
    	at Work2$MetaFilenameFilter.<init>(Work2.java:67)
    Avec la ligne 67 qui correspond à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    regexpPattern = regexpPattern.replaceAll("\\\\Q\\\\E", "");
    J'execute avec java 6. Une idée sur le problème ?

  6. #6
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    retire \\
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    regexpPattern = regexpPattern.replaceAll("\\Q\\E", "");

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conseils architecture type LINUX
    Par azigui91 dans le forum RedHat / CentOS / Fedora
    Réponses: 3
    Dernier message: 10/12/2010, 17h03
  2. [generics] Génériques à types multiples
    Par sanchou dans le forum Langage
    Réponses: 6
    Dernier message: 06/07/2007, 09h42
  3. Spécifier type de système de fichiers sous linux
    Par rond24 dans le forum Administration système
    Réponses: 4
    Dernier message: 07/03/2006, 20h09
  4. comment gérer le type HANDLE sous linux?
    Par poune dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 11/06/2004, 11h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo