Anthony
Anthony

Reputation: 1

JAVA - Array Out of Bounds Error

I have an issue with my logic and I would appreciate some pointers. My code produces the Array Out Of Bounds Exception when I try to iterate through an array of files in a directory and store the files that end in .txt within another array.

I think my issue is that the array of all files is larger than the array of txt files, that seems the most logical reason for the error. The problem is I don't know why its finding more occurrences of txt files in the second loop vs the first.

Here is the code:

public static void ListFiles(String file_dir) {
        String files;
        int txtCounter = 0;

        File folder = new File(file_dir);
        File[] listOfFiles = folder.listFiles(); 

        //Count all txt files
        for (int y = 0; y < listOfFiles.length; y++) {
            if (listOfFiles[y].isFile()) {
                files = listOfFiles[y].getName();
                if (files.endsWith(".txt") || files.endsWith(".TXT")) {
                    txtCounter++;//Add to the count
                }
            }
        }

        //Create array for the list of txt files.
        String txtFiles[] = new String[txtCounter];

        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                files = listOfFiles[i].getName();
                if (files.endsWith(".txt") || files.endsWith(".TXT")) {
                    //Add all txt files to new array txtFiles
                    txtFiles[i] = folder + files;                   
                    System.out.println(txtFiles[i]);
                }
            }
        }

        //Send array back to Main
        //return txtFiles[];
    }

Am I making this harder than it has to be? I'm trying to take a list of text files, replace certain words in the files, and combine them all into one file when complete.

Thanks!

UPDATED:

public static String[] ListManualSections(String file_dir) {
    file_dir = file_dir + "\\manualSections\\";

    String files;

    //Create list of all files in the manualSections directory.
    File folder = new File(file_dir);
    File[] listOfFiles = folder.listFiles(); 

    //Dynamic list of text files
    ArrayList al = new ArrayList();

    //Add each occurrence of a text file to the ArrayList
    for (int i = 0; i < listOfFiles.length; i++) {
        files = listOfFiles[i].getName();
        if (listOfFiles[i].isFile() && files.toLowerCase().endsWith(".txt")) {
            al.add(folder + "\\" + files);
            //System.out.println(al);
        }
    }

    //Send list back to Main
    String[] txtFiles = (String[]) al.toArray(new String[al.size()]);
    return txtFiles;
}

Upvotes: 0

Views: 675

Answers (7)

NominSim
NominSim

Reputation: 8511

Your second for loop iterates over all of the files, meaning that i = 0 .. N where N is the number of total files. But your text files could occur at any i here. The so even if there are only 2 text files, if they are found on the 6th iteration of the N total files, that is not the index you want to be using for your text file array.

I would suggest you create a counter for the index of the text file array and increment it as you add, or use a List.

String txtFiles[] = new String[txtCounter];
int txtIndex = 0;

for (int i = 0; i < listOfFiles.length; i++) {
    if (listOfFiles[i].isFile()) {
        files = listOfFiles[i].getName();
        if (files.endsWith(".txt") || files.endsWith(".TXT")) {
            //Add all txt files to new array txtFiles
            txtFiles[txtIndex] = folder + files;
            txtIndex++;                   
            System.out.println(txtFiles[i]);
        }
    }
}

Upvotes: 0

Ashwinee K Jha
Ashwinee K Jha

Reputation: 9307

You could simply use File.listFiles(FileNameFilter) to get the files matching your criteria.

private File[] getTextFiles(String dir)
{
    File folder = new File(dir);

    return folder.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".txt");
        }           
    });
}

Upvotes: 0

Sterling
Sterling

Reputation: 4213

Well look at this scenario -

listOfFiles is size 6, first loop you find 5 txt files, and the last element in listOfFiles is a txt file.

Then at the last iteration of second loop, you are trying to do txtFiles[5] = folder+files. That will throw the error because txtFiles is only 0-4.

Like Louis said, use ArrayList.

Upvotes: 0

Vlad
Vlad

Reputation: 35594

As addition to the answer of @Louis, you could go with a separate counter for the file and txt-file. Like this:

int txtidx = 0;
for (int i = 0; i < listOfFiles.length; i++) {
    if (listOfFiles[i].isFile()) {
        files = listOfFiles[i].getName();
        if (files.endsWith(".txt") || files.endsWith(".TXT")) {
            //Add all txt files to new array txtFiles
            txtFiles[txtidx] = folder + files;                   
            System.out.println(txtFiles[txtidx]);
            txtidx++;
        }
    }
}

Upvotes: 2

Uchenna Nwanyanwu
Uchenna Nwanyanwu

Reputation: 3204

instead of complicating matters, you can do this

Use Apache Commons io to list all your files

    Collection<File> files = FileUtils.listFiles(new File("file_dir"), new String[]{"txt"}, true);

//use true if you want it to be recursive, i.e. to search subdirectories of file_dir

for (File file : files)
{
    //you can then play with your file object here
}

Let me know if you have issues.

Upvotes: 1

Dancrumb
Dancrumb

Reputation: 27539

You're making this harder than it has to be.

You're passing over an array once to count how many text files there are and then, a second time, to add text files to another array.

Any implementer of the List<E> interface would be more appropriate than an array; you can then add elements on the fly. If you must have an array afterwards. you can always use the toArray method at the end.

Upvotes: 0

Louis Wasserman
Louis Wasserman

Reputation: 198093

This second for loop seems confused about whether it's iterating over txtFiles or over listOfFiles, which could have different lengths. In particular, you should probably not be writing to txtFiles[i] when i could be larger than the length of txtFiles.

Mostly, though, this code would be simpler if you just used an ArrayList.

Upvotes: 4

Related Questions