0

i want to see if a certain directory contains a jpg file. What is the best way (one way) to do this? If the directory didnt have any sub folders it would be easy, but now i want to move through directories to find jpg. For ex:

public static boolean dirHasJpg(File[] files){
    //files is the first directory
    for(File file : files){
        if(file.getName().toLowerCase().endsWith("jpg")){
            return true;
        }else if(file.isDirectory()){
            //move in to a subdirectory.
            for (File f2 : file.listFiles()){
                if(f2.getName().toLowerCase().endsWith("jpg")) {
                    return true;
                }else if(f2.isDirectory()){
                    and so on....
                }
            }
        }
    }
    return false;
}

I understand that is should be a while loop somewhere, but i just cannot figure out how to implement it, something along the lines of.

    for(File file : files){
        while (file.isDirectory()){
            //check that directory and all subdirectories
        }
    }
user3711421
  • 1,658
  • 3
  • 20
  • 37
  • It is a basic recursion: Check all files, then for all folders, open folder and check files in there, a basic recursion ... – paulgavrikov Jan 28 '15 at 20:27
  • Remember to search the stackoverflow first before posting. What you are looking for is something like this: [http://stackoverflow.com/questions/8489649/how-to-pick-all-files-from-folders-and-subfolders-in-android](http://stackoverflow.com/questions/8489649/how-to-pick-all-files-from-folders-and-subfolders-in-android), oh didn't saw @bluewhile already told to use a recursive function. – Oliver Nybroe Jan 28 '15 at 20:29
  • http://en.wikipedia.org/wiki/Recursion_%28computer_science%29 – njzk2 Jan 28 '15 at 21:04

3 Answers3

1

You're almost there! You have the basic structure down, but what you are missing is a recursive call to the method you already defined. Here's a sample:

public static boolean dirHasJpg(File[] files){
    // Iterate over the contents of the given file list
    for(File file : files){
        if (file.isFile()) {
            // If you were given a file, return true if it's a jpg
            if (file.getName().toLowerCase().endsWith("jpg")) {
                return true;
            }
        } else if (file.isDirectory()){
            // If it is a directory, check its contents recursively
            if (dirHasJpg(file.listFiles())) {
                return true;
            }
        }
    }
    // If none of the files were jpgs, and none of the directories contained jpgs, return false
    return false;
}

Though in this case, it might be better to rename the method to containsJpg() or even make it more reusable by defining the method as either boolean containsFileType(String fileExtension) or boolean containsFileType(String[] fileExtensions)


Edit:

You asked in your comment about whether the if statements were necessary, so I will use an example. Lets say you have the following directory structure:

File0-1.txt
Folder1
---- file1-1.txt
---- file1-2.txt
Folder2
---- file2-1.txt
---- file2-2.jpg

If we simply used return file.getName().toLowerCase().endsWith("jpg") without the if statement, it would find File0-1.txt and return false. Therefore because it returned without continuing to check the rest of the files/directories, it would miss file2-2.jpg. The same thing can be said about return dirHasJpg(file.listfiles()): it would return false for Folder1 and would not reach Folder2 that contains the jpg file.

bajuwa
  • 330
  • 1
  • 9
  • I just noticed there is a logical error in the code I gave you, whoops! I've edited it to correct the following mistake: if the first file it encountered was not a jpg, it would return false prior to checking the rest of the contents. In the corrected algorithm, it now only returns false if all the contents (and subcontents) have been explored. – bajuwa Jan 28 '15 at 21:57
  • Hmm, i actually made it work before your answer and it was similar to what you had written. I really like the extension part so included that, so the header would be directoryContainsFileExtension(String[] fileExtensions, File[] files)....And wouldnt it work to :::: return dirHasJpg(file.listFiles()) ........Instead of the if statement? How did your code look like before editing? – user3711421 Jan 28 '15 at 22:13
  • Now i see :). My code was identical but for the file.isFile().. I went directly to -> if(file.getName().toLowerCase().endsWith("jpg") ... However, about the return dirHasJpg(file.listFiles()),,, is the if statement really necessary? – user3711421 Jan 28 '15 at 22:21
  • Added an edit to explain the necessary changes for the if statements – bajuwa Jan 28 '15 at 22:32
0

Following code snippet can be helpful :

    public void CheckFile(String directoryName) {
    File directory = new File(directoryName);

    // get all the files from a directory
    File[] fList = directory.listFiles();
    for (File file : fList) {
        if (file.isFile() && getFileExt(file.getName()) == "jpg") {
          //file is your jpg :)
        } else if (file.isDirectory()) {
            CheckFile(file.getAbsolutePath());
        }
    }
}



public static String getFileExt(String FileName){
     return FileName.substring((FileName.lastIndexOf(".") + 1), FileName.length());
    }
0

I made an app that lists image files from an USB stick, for that purpose I list all the files corresponding to particular extensions, in your case you would just want to list "jpg" files...

You may need the Apache FileUtils (org.apache.commons.io.FileUtils and dependencies)...

Here is an extract of my code :

        File directory  = new File("/storage/UsbDriveA/");
        if (directory != null) {
            if (directory.canRead()) {
                ArrayList<File> = images = new ArrayList<File>();
                String[] imageExtensions = {"jpg","jpeg","JPG","JPEG"};
                Iterator<File> iterateImages = FileUtils.iterateFiles(directory, imageExtensions, true); // put this latest argument to false if you do not want to iterate recursively
                while (iterateImages.hasNext()) {
                    File theImage = iterateImages.next();
                    if (!theImage.getName().startsWith(".", 0))
                        images.add(theImage);

                }

                if (images.size() > 0)
                {
                    // ok you have at least 1 jpg file
                }
            }
        }
JBA
  • 2,889
  • 1
  • 21
  • 38