7 Replies - 852 Views - Last Post: 03 November 2014 - 01:04 PM Rate Topic: -----

#1 Invoker   User is offline

  • D.I.C Head
  • member icon

Reputation: 32
  • View blog
  • Posts: 165
  • Joined: 29-April 14

Recursively reading files within Directories

Posted 01 November 2014 - 05:56 PM

I'm at a breaking point and mentally starved, so I'm hoping you awesome guys/gals could help me out here.
Wrapping up this intro to java/programming course and recursion has hit me hard with an Inception effect.

I just can't seem to figure it out how to solve this inherently recursive assignment.The task is to check a directory path and read the files within that path; also, if there are more directories within it, we have to go deeper into those directories to read the files within them - if any.

What you're looking at is my skeleton of the assignment:

public class SearchingForStrings {

    public static void main(String[] args) {
        String path = "."; // Default
        File sf = new File(path);
        String mainDirectory = args[0]; // These two are just
        String keyString = args[1];          // command-line arguments

        countLinesWithString(sf, mysteriesDirectory, keyString);
    }

    public static int countLinesWithString(File startPath, String mainDirectory, String keyString) {
        if(!startPath.exists()) {
            throw new IllegalArgumentException("File " + startPath + " does not exist!");
        } else if(startPath.isFile()) {
            // Just to show where the file is located
            // Temporary parsing to postpone an error
            //TODO: Consider removing this
            return Integer.parseInt(startPath.getAbsolutePath());
        } else if(startPath.isDirectory()) {
            // This is where our recursion would take place: essentially
            // we will be going 'deeper' into the directory until we find a file

            countLinesWithString(startPath, mainDirectory, keyString);
        } else {
            throw new IllegalStateException("Unknown file type: " + startPath);
        }
    }
}



Could someone explain this; feel free to ask for more information if needed


P.S. I've read just about every Oracle database/tutorial on recursion (They aren't helping).

This post has been edited by Invoker: 01 November 2014 - 08:44 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Recursively reading files within Directories

#2 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 12350
  • View blog
  • Posts: 20,984
  • Joined: 19-March 11

Re: Recursively reading files within Directories

Posted 01 November 2014 - 07:46 PM

I'm not sure where mysteriesDirectory is coming from or what it means, but it doesn't seem to exist in either of the places where it's referenced. Might want to clear that up.
Was This Post Helpful? 0
  • +
  • -

#3 Invoker   User is offline

  • D.I.C Head
  • member icon

Reputation: 32
  • View blog
  • Posts: 165
  • Joined: 29-April 14

Re: Recursively reading files within Directories

Posted 01 November 2014 - 08:41 PM

Mysteries (mainDirectory) is simply a folder(directory name - the main one) it then contains other folders each housing there own files some with and some with none. Sorry for confusion.

I changed the name to match the actual folders name - forgot to rename it there.

This post has been edited by Invoker: 01 November 2014 - 08:46 PM

Was This Post Helpful? 0
  • +
  • -

#4 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7507
  • View blog
  • Posts: 15,558
  • Joined: 16-October 07

Re: Recursively reading files within Directories

Posted 02 November 2014 - 02:34 PM

public static int countLinesWithString(File startPath, String mainDirectory, String keyString) {
    //...
    // since none of these three values have changed... 
    // welcome to your infinite loop
    countLinesWithString(startPath, mainDirectory, keyString);



That you're calling this without processing a return type is rather troubling. Your mainDirectory parameter is fundamentally pointless. The return parseInt of a path name makes no sense at all.

You seem to be a few steps ahead of yourself. Before you can do anything clever, you need to actually be able to to traverse a directory. If you can get that far, then you're ready to starting worrying about doing something with the files you find.

e.g.
void dumpDir(File file) {
    if(!file.exists()) {
        throw new IllegalArgumentException("File " + file + " does not exist!");
    } else if(file.isFile()) {
        // why don't you just print that out?
        // using what you have
        System.out.println("FILE: " + file.getAbsolutePath());
    } else if(file.isDirectory()) {
        System.out.println("DIR: " + file.getAbsolutePath());
        // now, this is the fun part
        for(File child : // your call here
            dumpDir(child);
        }
    } else {
        // this is also kind of pointless: if you don't know how to process it, ignore it
        throw new IllegalStateException("Unknown file type: " + file);
    }
}


Was This Post Helpful? 1
  • +
  • -

#5 Invoker   User is offline

  • D.I.C Head
  • member icon

Reputation: 32
  • View blog
  • Posts: 165
  • Joined: 29-April 14

Re: Recursively reading files within Directories

Posted 02 November 2014 - 02:47 PM

Yea, realized that last night, and kinda started over. Here's what I'm currently working with:

    public static int countLinesWithString(String root, String keyString) throws FileNotFoundException {
        
        // I'm not sure if this line is necessary, but it's here because I was getting an error 
        // something about java.io.file to string (or vice verse)  
        File file = new File(root);
        File[] listFiles = file.listFiles();
        int countedLines = 0;
        if (file.isFile()) {
            System.out.println("File Name: " + file.listFiles());
            System.out.println();
            try(Scanner inscan = new Scanner(file)) {
                while(inscan.hasNextLine()){
                    while(inscan.hasNext()) {
                        if(inscan.next().equals(keyString)) {
                            countedLines += 1;
                        }
                    }
                }
            }

        } else {
            // If the file inside of the directory turns out to be a subdirectory
            // we recursively enter that directory by calling the method again
            // with the files absolute path as the directory
            for (File rootInDirectory : listFiles) {
                if(!rootInDirectory.isFile()) {
                    // this is where you would read the files contents
                    countLinesWithString(rootInDirectory.getAbsolutePath(), keyString);
                }
            }
        }
    return countedLines;
    }
}



I think my traversal is alright; double check for me, if you don't mind.

This post has been edited by Invoker: 02 November 2014 - 02:49 PM

Was This Post Helpful? 0
  • +
  • -

#6 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7507
  • View blog
  • Posts: 15,558
  • Joined: 16-October 07

Re: Recursively reading files within Directories

Posted 03 November 2014 - 05:06 AM

You're close. However, you're still ignoring the result of your recursive call. That needs to be rolled up into your total result.

e.g.
int countLinesWithString(File file, String keyString) throws FileNotFoundException {
    // don't do this yet
    // File[] listFiles = file.listFiles();
    // int countedLines = 0;
    if (file.isFile()) {
        System.out.println("File Name: " + file.listFiles());
        System.out.println();
        return getCount(file, keyString); // this method you write, easier to read if not in traversal.  You can even block that thrown exception, if you like
    } else {
        // now you need this var
        int countedLines = 0;
        for (File rootInDirectory : file.listFiles()) {
            // no
            // if(!rootInDirectory.isFile()) 
            // almost
            // countLinesWithString(rootInDirectory.getAbsolutePath(), keyString);
            // instead
            countedLines += countLinesWithString(rootInDirectory, keyString);
            // Note, don't constantly go string -> file -> string; stick with file
        }
        return countedLines;
    }
}



Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#7 Invoker   User is offline

  • D.I.C Head
  • member icon

Reputation: 32
  • View blog
  • Posts: 165
  • Joined: 29-April 14

Re: Recursively reading files within Directories

Posted 03 November 2014 - 05:46 AM

countedLines += countLinesWithString(rootInDirectory, keyString);



I'm having a hard time understanding what's going on in this part of the code. I get that this is the recursive call, but I can't see how it's adding the String (that's being looked for in the files) into countedLines if this is the else statement that checks for directories and goes 'deeper'.

Also for the getCount(file, keyString) method is this returning or is this a void method? Normally I'd be able to tell if this were the case, but I'm too concentrated on understanding the 'flow' of recursion.

This is what I've written for the getCount() method:

    public static int getCount(File root, String keyString) throws FileNotFoundException {
        int countedLines = 0;

        try(Scanner inscan = new Scanner(root)) {
            while(inscan.hasNextLine()){
                while(inscan.hasNext()) {
                    if(inscan.next().equals(keyString)) {
                        countedLines += 1;
                    }
                }
            }
        }
        // not sure if this is supposed to return this value back to the method because 
        // countedLines isn't initialized in this part of the if-else loop.
        return countedLines;
    }


ALSO: I've gone ahead and made a test main method just to see what this produces, as I'm pretty sure once this stuff is done that's all the program needs. I'm not sure if my computer is just slow or this is producing infinite recursion.

UPDATE 1: After careful examination, I've figured out my initial question in this comment. For those who look at this and are curious: the getCount() method must return an int value because when the else statement calls the recursive method - if a file is found - it will then call the getMethod() (which returns an int) and add that int value into the countedLines variable.

This post has been edited by Invoker: 03 November 2014 - 06:21 AM

Was This Post Helpful? 0
  • +
  • -

#8 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7507
  • View blog
  • Posts: 15,558
  • Joined: 16-October 07

Re: Recursively reading files within Directories

Posted 03 November 2014 - 01:04 PM

Each call to countLinesWithString is discrete. It takes two values, path and keyString, and returns a count.

Imagine we're actually walking a directory structure:
root
 f alpha.txt
 d bravo
   f foxtrot.txt
   d golf
     f juliet.txt
   f hotel.txt
 f charlie.txt
 f delta.txt
 d echo
   f india.txt



Now, walk the recursion:
call("root", "needle")
 return 
   call("root/alpha.txt", "needle")
   + call("root/bravo", "needle")
   + call("root/charlie.txt", "needle")
   + call("root/delta.txt", "needle")
   + call("root/echo", "needle")

-- but, when you call something like root/bravo, you in turn get
call("root/bravo", "needle")
 return
   call("root/bravo/foxtrot.txt", "needle")
   + call("root/bravo/golf", "needle")
   + call("root/bravo/golf/juliet.txt", "needle")
-- of course, call("root/bravo/golf", "needle") also descends



Hope this helps.
Was This Post Helpful? 2
  • +
  • -

Page 1 of 1