Reputation: 1
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
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
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
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
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
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
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
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