Rechercher un fichier ou un dossier dans la carte SD.

Dimanche 29 juillet 2012, 22:22

Bonjour à tous,

Aujourd’hui je vais vous partager mon deuxième fichier « util« , qui me sert a récupérer certains fichier dans ma carte sd.

C’est d’une simplicité enfantine, on donne le nom d’un dossier, ou le nom d’un fichier en paramètre et il nous renvoie soit le fichier, soit null.

import java.io.File;
import java.io.IOException;
import android.os.Environment;

/**
 * Class utilitaire pour chercher un fichier avec son nom. Try catch si
 * nullpointer = pas trouve de fichier
 * 
 * @author Laurent
 * 
 */
public class FileSearch {

    /**
     * Methode qui va rechercher dans la sdcard le fichier avec le nom.
     * 
     * @param fileName le nom du fichier
     * @return le fichier en lui meme
     */
    public static File chercherFichier(String fileName) throws NullPointerException {
        File root = Environment.getExternalStorageDirectory();
        File out = null;
        out = chercherFichierRec(root, fileName);
        return out;
    }

    private static File chercherFichierRec(File dossier, String fileName) throws NullPointerException {
        File out = null;
        File[] contenuDossier;
        contenuDossier = dossier.listFiles();
        for (File f : contenuDossier) {
            if (f.isFile() && f.getName().equals(fileName))
                /** Log.d("fichier ? ", f.getPath()); */
                return f;
        }

        for (File f : contenuDossier) {
            if (f.isDirectory()) {
                out = chercherFichierRec(f, fileName);
                if (out != null) {
                    return out;
                }
            }
        }
        return out;
    }

    /***
     * cherche le dossier par le nom
     * 
     * @param fileName
     * @return
     */
    public static File chercherDossier(String fileName) throws NullPointerException {
        File root = Environment.getExternalStorageDirectory();
        File out = null;
        out = chercherDossierRec(root, fileName);
        return out;
    }

    private static File chercherDossierRec(File dossier, String fileName) throws NullPointerException {
        File out = null;
        File[] contenuDossier;
        contenuDossier = dossier.listFiles();
        for (File f : contenuDossier) {
            /** Log.d("dossier ? ", f.getPath()); */
            if (f.isDirectory() && f.getName().equals(fileName))
                return f;
        }

        for (File f : contenuDossier) {
            if (f.isDirectory()) {
                out = chercherDossierRec(f, fileName);
                if (out != null) {
                    return out;
                }
            }
        }
       return out;
   }

   /**
    * supprime tous les fichiers et dossier dans ce dossier.
    * supprime le dossier en tant que tel, si true.
    * @param root
    * @throws IOException 
    */
   public static void deleteAllFileFolder(File root, boolean delete) throws IOException {
      for (String path : root.list()) {
          File temp = new File(root.getPath() + File.separator + path);
          if (temp.isFile()) {
              temp.getCanonicalFile().delete();
          } else if (temp.isDirectory()) {
              if (temp.list().length == 0) {
                  temp.getCanonicalFile().delete();
              } else {
                  deleteAllFileFolder(temp, true);
                  temp.getCanonicalFile().delete();
              }
          }
      }
      if (delete) {
          root.getCanonicalFile().delete();
      }
   }
}

Et la dernière méthode supprime totalement un dossier avec ses dossiers enfants et fichiers enfants. (Cela m’aide pour mes tests quand j’ai la flemme de supprimer non-stop les fichiers que j’ai créé) Sur ce les amis, je vous souhaite une bonne semaine, à bientôt !

A propos de l'auteur
Laurent

Développeur Java & mobile, plus particulièrement sur Android, passionné par les technologies mobile et la S-F, je travail pour VLS Henrotte une entreprise basé à Liège. Autodidacte, motivé et surtout très ouvert à tout ce qui approche de l’innovation ou la révolution, je partage mes connaissances ou mes sources. Je suis aussi un twitterfou

Laisser un commentaire

Commentaires

Salut, je me suis permit d’améliorer quelques trucs dans ta classe ici : http://pastebin.com/fAd753RY, à commencer par les exceptions.

Il faut plutôt lancer des FileNotFoundException au lieu des NullPointerException qui n’ont rien à faire là car ce sont des erreurs de runtime donc réserver à la JVM.

Ensuite les final qui manque partout, surtout sur la classe étant donnée que c’est une classe utilitaire elle ne sera pas étendue. Pareil avec le constructeur privée vide étant donner que toutes les méthodes d’une classe utilitaires sont en static, on a pas besoin d’avoir une instance de la classe.

J’ai ensuite améliorer un peux le code de parcours récursive des dossiers. Bon dans mon exemple j’utilise des break pour sortir des boucles for lorsqu’on a trouvé notre fichier, c’est pas super propre algorithmiquement parlant mais ça marche et ça peux pas mal réduire le nombre d’itération. Sachant que je mon code comme le tien retourne le premier fichier trouvé, s’il y en a plusieurs avec le même nom il faudrait changer les méthodes pour retourner une liste de fichiers.

Ha et j’ai oublié mais on devrait aussi tester la String fileName au début pour savoir si elle est null ou vide et dans ce cas lancer une IllegalArgumentException.

Voilà c’est a peut près tout ce que j’ai noté, le code que je t’ai donné a était fait à la va vite et pour du Java SE, je l’ai pas tester sur du Java ME mais normalement il marche sans problème.
Pour info voilà une des classe utilitaire sur les fichiers présente dans Geotoolkit.org (un des projets open source sur lequel je travail dans ma boite) http://hg.geotoolkit.org/geotoolkit-pending/files/tip/modules/utility/geotk-utility-pending/src/main/java/org/geotoolkit/util/FileUtilities.java.
Il y a aussi beaucoup de truc utile dans la classe Files http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html

En espérant t’avoir aider.

Hello, tout d’abord merci pour ton commentaire fort constructif :-)
J’avoue faire très peu de classe utilitaire, donc je ne pense jamais au final ^^.

J’y avais pensé au paramètre à tester, et même a tester le LowerCase :-)
Vu qu’Android est plus ou moins basé sur du SE et non pas du ME ça passera sans problème.

J’irais voir ton utilitaire, ça pourrait peut-être m’être utile plus tard.

Merci à toi ;-)

De rien, plus généralement il faut utiliser le final le plus possible. Personnellement, dès que je déclare une variable elle est d’office en final et je retire le final si j’ai besoin de la réaffecter plus tard. Le final permet à la JVM d’optimiser le code et la gestion du garbage collector. Même si c’est pas flagrant, ça permet de rendre le code un peut plus optimiser et surtout plus robuste.

Pas bête, toujours intéressant de le savoir, merci ;-)