JAVA - Array Out of Bounds Error - java

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;
}

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.

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++;
}
}
}

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.

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.

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.

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");
}
});
}

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]);
}
}
}

Related

How to check if a folder contains n file with a certain path

I'm developing an Android app, I have to implement a function that returns an integer.
I have a folder with different files, each file is composed from a custom path like this:
123_part_ax0.jpg
123_part_ax1.jpg
123_part_ax2.jpg
123_part_ax3.jpg
123_part1_ax0.jpg
123_part1_ax1.jpg
I need to count all file that have the same path like: 123_part_ax in this case count = 4.
* Solution that I used *
public int itemNumber(int id) {
int nItem = 0;
File dir = new File(Environment.getExternalStorageDirectory() + "/.PATH/"+id);
File[] listOfFiles = dir.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if(listOfFiles[i].getName().contains("WHAT I WHAT SEARCH")){
nItem++;
}
}
return nItem;
}
For such need, you can use either File#list(FilenameFilter filter) or File#listFiles(FilenameFilter filter) to filter the content of your folder by file name then get the length of the resulting array.
For example with list(FilenameFilter):
int total = new File("/path/to/my/folder")
.list((dir, name) -> name.startsWith("123_part_ax"))
.length;

Having a variable from another class as the file name (GUI)

One class of my GUI has a variable for the file name. I want to pass this to another class so that I can process a file without having to hard code the file's name every time. The program compiles fine but I can't seem to run it correctly.
public void run() {
WordsCounter2 fileName = new WordsCounter2();
essayName = fileName.getFileList();
File f = new File(essayName);
//other code
WordsCounter2 is the class that houses the variable fileName, I'm calling it from this class and assigning it as the file's name, but this doesn't work. Could someone help?
if (rVal == JFileChooser.APPROVE_OPTION) {
File[] selectedFile = fileChooser.getSelectedFiles();
fileList = "nothing";
if (selectedFile.length > 0)
fileList = selectedFile[0].getName();
for (int i = 1; i < selectedFile.length; i++) {
fileList += ", " + selectedFile[i].getName();
}
statusBar.setText("You chose " + fileList);
}
else {
statusBar.setText("You didn't choose a file.");
}
fileList isn't empty because I have a label on the GUI that lists whatever file I chose.
Here's my new edit: now the exception occurs at the last line with the scanner and throws a NPE. Can you help?
public void run() {
WordsCounter2 pathNamesList = new WordsCounter2();
essayName = pathNamesList.getPathNamesList();
essayTitle = new String[essayName.size()];
essayTitle = essayName.toArray(essayTitle);
for (int i = 0; i < essayTitle.length; i++) {
f = new File(essayTitle[i]);
}
try {
Scanner scanner = new Scanner(f);
Your code is failing because File will not accept comma separated file names, in fact, it needs a single file path to create the file in the mentioned path. See here: https://docs.oracle.com/javase/7/docs/api/java/io/File.html
You'll have to get complete paths in an array and put the file creation statement as follows:
File f;
for (int i=0; i<fileList.length; i++)
f = new File(fileList[i]);
where fileList is a String array holding the list of pathnames.
In case you're trying to write some content to these files as well, this should be helpful: Trying to Write Multiple Files at Once - Java

filenames from catalog path in javafx

I want to get filnames from catalog path in Javafx 2 without extensions, but with filters (*.jpeg, *.jpg...).
Filenames should be as list of strings. But I don't know how can I do it.
If anybody know how do it, please for help.
For example manually manage such files
File f = new File("D:\\dir_name\\");
if (f.isDirectory()) {
String[] list = f.list();
for (int pos = 0; pos < list.length; pos++) {
if (list[pos].contains(".")//contains extension
&& list[pos].lastIndexOf(".") != (list[pos].length() - 1))//point is not last character
{
list[pos]=list[pos].substring(0,list[pos].lastIndexOf("."));
}
}
}

java listing the txt files in sub folders

Hi I have a jlist and currently it is viewing a folder + subfolders... Now i would like to change this to view the files in the subfolders as well. below please find the code I am currently using:
jList1.setModel(new javax.swing.AbstractListModel()
{
File folder = new File ("/Assignment_Datex/message_outbox/");
File[] listofFiles = folder.listFiles();
// #Override
public int getSize()
{ return listofFiles.length; }
// #Override
public Object getElementAt(int i)
{ return listofFiles[i];}
}
);
Right now as you can see in the screenshot, the Jlist is only viewing the folders and not the files in them... Any help please?
If you want to show all files and folder under some root folder then you should try someting like this...
Get files and folders under root folder.
Loop over them and check if it is file or folder.
If file then just add to list nothing more.
If folder then add it to list and repeat this same steps for that folder until all folder and files are traveled.
I can not produce whole code here but this is a prototype for this:
void addFilesToList(File folder){
File[] listofFiles = folder.listFiles();
for(File file:listofFile){
if(file.isFile()) // --- file
list.add(file.getName());
else{ // --- folder
addFileToList(file);
}
}
}
The above code is not tested so may need to modify it to fit your need.
#Harry Joy is right.
Additionally you can also use FindFile from jakarta project. It can save your time.
You create a constructor to initialise your class, and there you put (tested and working)
// initialize the class variable
listofFiles = new ArrayList();
// initialize with the path
File f = new File("/home/albertmatyi/Work/python/");
// create a temporary list to work with
LinkedList files = new LinkedList();
// fill it with the contents of your path
files.addAll(Arrays.asList(f.listFiles()));
while (!files.isEmpty()) {
// keep removing elements from the list
f = files.pop();
// if it is a directory add its contents to the files list
if (f.isDirectory()) {
files.addAll(Arrays.asList(f.listFiles()));
// and skip the last if
continue;
}
// check if it's a text file, and add it to listofFiles
if (f.getName().endsWith(".txt"))
listofFiles.add(f);
}
EDIT:
Note:
I've changed the type of listofFiles to ArrayList<File>, which has to be initialized in the constructor using:
listofFiles = new ArrayList<File>();
This allows easier manipulation of the data - no need to manually allocate bigger space for when more text files need to be added
I think this is good way to read all .txt files in a folder and sub folder's
private static void addfiles (File input,ArrayList<File> files)
{
if(input.isDirectory())
{
ArrayList <File> path = new ArrayList<File>(Arrays.asList(input.listFiles()));
for(int i=0 ; i<path.size();++i)
{
if(path.get(i).isDirectory())
{
addfiles(path.get(i),files);
}
if(path.get(i).isFile())
{
String name=(path.get(i)).getName();
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(path.get(i));
}
}
}
}
}
if(input.isFile())
{
String name=(input.getName());
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(input);
}
}
}
}
Now you have a list of files that you can do some process on it!

find same file with in many directories in hierarchical directories in java

I am trying to get a report file which is generated for many applications and stored in directories. But i am not able to get every report when i search through java. Can any 1 please help me with this matter.
if you want to search the file in a directory that has subdirectory and goes on then use a recursive search.you can see an example here http://www.exampledepot.com/egs/java.io/TraverseTree.html
http://www.java2s.com/Code/Java/File-Input-Output/Searchforfilesrecursively.htm
private static File find(File dir, String name) {
File result = null; // no need to store result as String, you're returning File anyway
File[] dirlist = dir.listFiles();
for(int i = 0; i < dirlist.length; i++) {
if(dirlist[i].isDirectory()) {
result = find(dirlist[i], name);
filedetails.add(result);
if (dirlist==null)
break;
// recursive call found the file; terminate the loop
} else if(dirlist[i].getName().matches(name)) {
return dirlist[i]; // found the file; return it
}
}
return result; // will return null if we didn't find anything
}
here is snippet where i am trying details of the file in a vector .
File Dir = new File("D:\\log");
File[] Dir2 = Dir.listFiles(); //Dir2 is inner directory
for(int j=0;j
/* The add gets the same file names which as differnt path and that vector can stored and used */

Categories