ArrayList with recursive method - java

I'm new to using Swing - I have a recursive method which iterates over directories on the hard drive and currently prints out the music tracks - I want to add the tracks to an array list so that I can send the complete list to a JPanel and display it there... How can I stop the array list being cleared when the method is called recursively for each folder? Thanks

I'm not sure that I understand your code, so I'll restart from scratch, by giving you some pseudo-code:
private List<File> getAllAudioFiles(File folder) {
List<File> result = new ArrayList<>();
// you want a single list. There should be no other list creation in the algorithm.
addAllAudioFiles(folder, result);
return result;
}
private void addAllAudioFiles(File folder, List<File> result) {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
// call this method recursively, to add all the audio files in the subfolder
// to the SAME list
addAllAudioFiles(file, result);
}
else if (isAudioFile(file)) {
result.add(file);
}
}
}

Try the following code
public class MusicGetter {
ArrayList<String> tlist = new ArrayList<>();
MusicGetter(String c) {
addToList(c);
}
private void addToList(String s) {
File root = new File(s);
File[] files = root.listFiles();
for (File f : files) {
String str = f.getPath();
if (str.endsWith(".mp3") || str.endsWith(".wav") || str.endsWith(".flac") || str.endsWith(".m4a") || str.endsWith(".ogg") || str.endsWith(".wma")) {
tlist.add(str);
}
if (f.isDirectory()) {
addToList(f.getPath().toString());
}
}
}
public static void main(String[] args) {
MusicGetter mg = new MusicGetter("E:\\audios");
for (int i = 0; i < mg.tlist.size(); i++) {
System.out.println(mg.tlist.get(i));
}
}
}

Related

How to get dynamic name of .zip file after download in JAVA [duplicate]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
How to read all the files in a folder through Java? It doesn't matter which API.
public void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
final File folder = new File("/home/you/Desktop");
listFilesForFolder(folder);
Files.walk API is available from Java 8.
try (Stream<Path> paths = Files.walk(Paths.get("/home/you/Desktop"))) {
paths
.filter(Files::isRegularFile)
.forEach(System.out::println);
}
The example uses try-with-resources pattern recommended in API guide. It ensures that no matter circumstances the stream will be closed.
File folder = new File("/Users/you/folder/");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile()) {
System.out.println(file.getName());
}
}
In Java 8 you can do this
Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
which will print all files in a folder while excluding all directories. If you need a list, the following will do:
Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.collect(Collectors.toList())
If you want to return List<File> instead of List<Path> just map it:
List<File> filesInFolder = Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
You also need to make sure to close the stream! Otherwise you might run into an exception telling you that too many files are open. Read here for more information.
All of the answers on this topic that make use of the new Java 8 functions are neglecting to close the stream. The example in the accepted answer should be:
try (Stream<Path> filePathStream=Files.walk(Paths.get("/home/you/Desktop"))) {
filePathStream.forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
System.out.println(filePath);
}
});
}
From the javadoc of the Files.walk method:
The returned stream encapsulates one or more DirectoryStreams. If
timely disposal of file system resources is required, the
try-with-resources construct should be used to ensure that the
stream's close method is invoked after the stream operations are completed.
One remark according to get all files in the directory.
The method Files.walk(path) will return all files by walking the file tree rooted at the given started file.
For instance, there is the next file tree:
\---folder
| file1.txt
| file2.txt
|
\---subfolder
file3.txt
file4.txt
Using the java.nio.file.Files.walk(Path):
Files.walk(Paths.get("folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
Gives the following result:
folder\file1.txt
folder\file2.txt
folder\subfolder\file3.txt
folder\subfolder\file4.txt
To get all files only in the current directory use the java.nio.file.Files.list(Path):
Files.list(Paths.get("folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
Result:
folder\file1.txt
folder\file2.txt
import java.io.File;
public class ReadFilesFromFolder {
public static File folder = new File("C:/Documents and Settings/My Documents/Downloads");
static String temp = "";
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Reading files under the folder "+ folder.getAbsolutePath());
listFilesForFolder(folder);
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
// System.out.println("Reading files under the folder "+folder.getAbsolutePath());
listFilesForFolder(fileEntry);
} else {
if (fileEntry.isFile()) {
temp = fileEntry.getName();
if ((temp.substring(temp.lastIndexOf('.') + 1, temp.length()).toLowerCase()).equals("txt"))
System.out.println("File= " + folder.getAbsolutePath()+ "\\" + fileEntry.getName());
}
}
}
}
}
In Java 7 and higher you can use listdir
Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file: stream) {
System.out.println(file.getFileName());
}
} catch (IOException | DirectoryIteratorException x) {
// IOException can never be thrown by the iteration.
// In this snippet, it can only be thrown by newDirectoryStream.
System.err.println(x);
}
You can also create a filter that can then be passed into the newDirectoryStream method above
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) throws IOException {
try {
return (Files.isRegularFile(path));
} catch (IOException x) {
// Failed to determine if it's a file.
System.err.println(x);
return false;
}
}
};
For other filtering examples, [see documentation].(http://docs.oracle.com/javase/tutorial/essential/io/dirs.html#glob)
private static final String ROOT_FILE_PATH="/";
File f=new File(ROOT_FILE_PATH);
File[] allSubFiles=f.listFiles();
for (File file : allSubFiles) {
if(file.isDirectory())
{
System.out.println(file.getAbsolutePath()+" is directory");
//Steps for directory
}
else
{
System.out.println(file.getAbsolutePath()+" is file");
//steps for files
}
}
Just walk through all Files using Files.walkFileTree (Java 7)
Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("file: " + file);
return FileVisitResult.CONTINUE;
}
});
If you want more options, you can use this function which aims to populate an arraylist of files present in a folder. Options are : recursivility and pattern to match.
public static ArrayList<File> listFilesForFolder(final File folder,
final boolean recursivity,
final String patternFileFilter) {
// Inputs
boolean filteredFile = false;
// Ouput
final ArrayList<File> output = new ArrayList<File> ();
// Foreach elements
for (final File fileEntry : folder.listFiles()) {
// If this element is a directory, do it recursivly
if (fileEntry.isDirectory()) {
if (recursivity) {
output.addAll(listFilesForFolder(fileEntry, recursivity, patternFileFilter));
}
}
else {
// If there is no pattern, the file is correct
if (patternFileFilter.length() == 0) {
filteredFile = true;
}
// Otherwise we need to filter by pattern
else {
filteredFile = Pattern.matches(patternFileFilter, fileEntry.getName());
}
// If the file has a name which match with the pattern, then add it to the list
if (filteredFile) {
output.add(fileEntry);
}
}
}
return output;
}
Best, Adrien
File directory = new File("/user/folder");
File[] myarray;
myarray=new File[10];
myarray=directory.listFiles();
for (int j = 0; j < myarray.length; j++)
{
File path=myarray[j];
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String s = "";
while (br.ready()) {
s += br.readLine() + "\n";
}
}
nice usage of java.io.FileFilter as seen on https://stackoverflow.com/a/286001/146745
File fl = new File(dir);
File[] files = fl.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isFile();
}
});
static File mainFolder = new File("Folder");
public static void main(String[] args) {
lf.getFiles(lf.mainFolder);
}
public void getFiles(File f) {
File files[];
if (f.isFile()) {
String name=f.getName();
} else {
files = f.listFiles();
for (int i = 0; i < files.length; i++) {
getFiles(files[i]);
}
}
}
I think this is good way to read all the 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())
{
files.add(path.get(i));
}
}
}
if(input.isFile())
{
files.add(input);
}
}
Simple example that works with Java 1.7 to recursively list files in directories specified on the command-line:
import java.io.File;
public class List {
public static void main(String[] args) {
for (String f : args) {
listDir(f);
}
}
private static void listDir(String dir) {
File f = new File(dir);
File[] list = f.listFiles();
if (list == null) {
return;
}
for (File entry : list) {
System.out.println(entry.getName());
if (entry.isDirectory()) {
listDir(entry.getAbsolutePath());
}
}
}
}
While I do agree with Rich, Orian and the rest for using:
final File keysFileFolder = new File(<path>);
File[] fileslist = keysFileFolder.listFiles();
if(fileslist != null)
{
//Do your thing here...
}
for some reason all the examples here uses absolute path (i.e. all the way from root, or, say, drive letter (C:\) for windows..)
I'd like to add that it is possible to use relative path as-well.
So, if you're pwd (current directory/folder) is folder1 and you want to parse folder1/subfolder, you simply write (in the code above instead of ):
final File keysFileFolder = new File("subfolder");
Java 8 Files.walk(..) is good when you are soore it will not throw Avoid Java 8 Files.walk(..) termination cause of ( java.nio.file.AccessDeniedException ) .
Here is a safe solution , not though so elegant as Java 8Files.walk(..) :
int[] count = {0};
try {
Files.walkFileTree(Paths.get(dir.getPath()), new HashSet<FileVisitOption>(Arrays.asList(FileVisitOption.FOLLOW_LINKS)),
Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file , BasicFileAttributes attrs) throws IOException {
System.out.printf("Visiting file %s\n", file);
++count[0];
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file , IOException e) throws IOException {
System.err.printf("Visiting failed for %s\n", file);
return FileVisitResult.SKIP_SUBTREE;
}
#Override
public FileVisitResult preVisitDirectory(Path dir , BasicFileAttributes attrs) throws IOException {
System.out.printf("About to visit directory %s\n", dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
void getFiles(){
String dirPath = "E:/folder_name";
File dir = new File(dirPath);
String[] files = dir.list();
if (files.length == 0) {
System.out.println("The directory is empty");
} else {
for (String aFile : files) {
System.out.println(aFile);
}
}
}
package com;
import java.io.File;
/**
*
* #author ?Mukesh
*/
public class ListFiles {
static File mainFolder = new File("D:\\Movies");
public static void main(String[] args)
{
ListFiles lf = new ListFiles();
lf.getFiles(lf.mainFolder);
long fileSize = mainFolder.length();
System.out.println("mainFolder size in bytes is: " + fileSize);
System.out.println("File size in KB is : " + (double)fileSize/1024);
System.out.println("File size in MB is :" + (double)fileSize/(1024*1024));
}
public void getFiles(File f){
File files[];
if(f.isFile())
System.out.println(f.getAbsolutePath());
else{
files = f.listFiles();
for (int i = 0; i < files.length; i++) {
getFiles(files[i]);
}
}
}
}
Just to expand on the accepted answer I store the filenames to an ArrayList (instead of just dumping them to System.out.println) I created a helper class "MyFileUtils" so it could be imported by other projects:
class MyFileUtils {
public static void loadFilesForFolder(final File folder, List<String> fileList){
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
loadFilesForFolder(fileEntry, fileList);
} else {
fileList.add( fileEntry.getParent() + File.separator + fileEntry.getName() );
}
}
}
}
I added the full path to the file name.
You would use it like this:
import MyFileUtils;
List<String> fileList = new ArrayList<String>();
final File folder = new File("/home/you/Desktop");
MyFileUtils.loadFilesForFolder(folder, fileList);
// Dump file list values
for (String fileName : fileList){
System.out.println(fileName);
}
The ArrayList is passed by "value", but the value is used to point to the same ArrayList object living in the JVM Heap. In this way, each recursion call adds filenames to the same ArrayList (we are NOT creating a new ArrayList on each recursive call).
There are many good answers above, here's a different approach: In a maven project, everything you put in the resources folder is copied by default in the target/classes folder. To see what is available at runtime
ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
URL resource = contextClassLoader.getResource("");
File file = new File(resource.toURI());
File[] files = file.listFiles();
for (File f : files) {
System.out.println(f.getName());
}
Now to get the files from a specific folder, let's say you have a folder called 'res' in your resources folder, just replace:
URL resource = contextClassLoader.getResource("res");
If you want to have access in your com.companyName package then:
contextClassLoader.getResource("com.companyName");
You can put the file path to argument and create a list with all the filepaths and not put it the list manually. Then use a for loop and a reader. Example for txt files:
public static void main(String[] args) throws IOException{
File[] files = new File(args[0].replace("\\", "\\\\")).listFiles(new FilenameFilter() { #Override public boolean accept(File dir, String name) { return name.endsWith(".txt"); } });
ArrayList<String> filedir = new ArrayList<String>();
String FILE_TEST = null;
for (i=0; i<files.length; i++){
filedir.add(files[i].toString());
CSV_FILE_TEST=filedir.get(i)
try(Reader testreader = Files.newBufferedReader(Paths.get(FILE_TEST));
){
//write your stuff
}}}
package com.commandline.folder;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class FolderReadingDemo {
public static void main(String[] args) {
String str = args[0];
final File folder = new File(str);
// listFilesForFolder(folder);
listFilesForFolder(str);
}
public static void listFilesForFolder(String str) {
try (Stream<Path> paths = Files.walk(Paths.get(str))) {
paths.filter(Files::isRegularFile).forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
}
We can use org.apache.commons.io.FileUtils, use listFiles() mehtod to read all the files in a given folder.
eg:
FileUtils.listFiles(directory, new String[] {"ext1", "ext2"}, true)
This read all the files in the given directory with given extensions, we can pass multiple extensions in the array and read recursively within the folder(true parameter).
public static List<File> files(String dirname) {
if (dirname == null) {
return Collections.emptyList();
}
File dir = new File(dirname);
if (!dir.exists()) {
return Collections.emptyList();
}
if (!dir.isDirectory()) {
return Collections.singletonList(file(dirname));
}
return Arrays.stream(Objects.requireNonNull(dir.listFiles()))
.collect(Collectors.toList());
}
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AvoidNullExp {
public static void main(String[] args) {
List<File> fileList =new ArrayList<>();
final File folder = new File("g:/master");
new AvoidNullExp().listFilesForFolder(folder, fileList);
}
public void listFilesForFolder(final File folder,List<File> fileList) {
File[] filesInFolder = folder.listFiles();
if (filesInFolder != null) {
for (final File fileEntry : filesInFolder) {
if (fileEntry.isDirectory()) {
System.out.println("DIR : "+fileEntry.getName());
listFilesForFolder(fileEntry,fileList);
} else {
System.out.println("FILE : "+fileEntry.getName());
fileList.add(fileEntry);
}
}
}
}
}
list down files from Test folder present inside class path
import java.io.File;
import java.io.IOException;
public class Hello {
public static void main(final String[] args) throws IOException {
System.out.println("List down all the files present on the server directory");
File file1 = new File("/prog/FileTest/src/Test");
File[] files = file1.listFiles();
if (null != files) {
for (int fileIntList = 0; fileIntList < files.length; fileIntList++) {
String ss = files[fileIntList].toString();
if (null != ss && ss.length() > 0) {
System.out.println("File: " + (fileIntList + 1) + " :" + ss.substring(ss.lastIndexOf("\\") + 1, ss.length()));
}
}
}
}
}
/**
* Function to read all mp3 files from sdcard and store the details in an
* ArrayList
*/
public ArrayList<HashMap<String, String>> getPlayList()
{
ArrayList<HashMap<String, String>> songsList=new ArrayList<>();
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
song.put(
"songTitle",
file.getName().substring(0,
(file.getName().length() - 4)));
song.put("songPath", file.getPath());
// Adding each song to SongList
songsList.add(song);
}
}
// return songs list array
return songsList;
}
/**
* Class to filter files which have a .mp3 extension
* */
class FileExtensionFilter implements FilenameFilter
{
#Override
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
You can filter any textfiles or any other extension ..just replace it with .MP3
This will Read Specified file extension files in given path(looks sub folders also)
public static Map<String,List<File>> getFileNames(String
dirName,Map<String,List<File>> filesContainer,final String fileExt){
String dirPath = dirName;
List<File>files = new ArrayList<>();
Map<String,List<File>> completeFiles = filesContainer;
if(completeFiles == null) {
completeFiles = new HashMap<>();
}
File file = new File(dirName);
FileFilter fileFilter = new FileFilter() {
#Override
public boolean accept(File file) {
boolean acceptFile = false;
if(file.isDirectory()) {
acceptFile = true;
}else if (file.getName().toLowerCase().endsWith(fileExt))
{
acceptFile = true;
}
return acceptFile;
}
};
for(File dirfile : file.listFiles(fileFilter)) {
if(dirfile.isFile() &&
dirfile.getName().toLowerCase().endsWith(fileExt)) {
files.add(dirfile);
}else if(dirfile.isDirectory()) {
if(!files.isEmpty()) {
completeFiles.put(dirPath, files);
}
getFileNames(dirfile.getAbsolutePath(),completeFiles,fileExt);
}
}
if(!files.isEmpty()) {
completeFiles.put(dirPath, files);
}
return completeFiles;
}
This will work fine:
private static void addfiles(File inputValVal, ArrayList<File> files)
{
if(inputVal.isDirectory())
{
ArrayList <File> path = new ArrayList<File>(Arrays.asList(inputVal.listFiles()));
for(int i=0; i<path.size(); ++i)
{
if(path.get(i).isDirectory())
{
addfiles(path.get(i),files);
}
if(path.get(i).isFile())
{
files.add(path.get(i));
}
}
/* Optional : if you need to have the counts of all the folders and files you can create 2 global arrays
and store the results of the above 2 if loops inside these arrays */
}
if(inputVal.isFile())
{
files.add(inputVal);
}
}

java listing directories in depth and making operations

I am trying to do some file editing in a directory which has some subfolders in it. However my java app doesnt go in depths of subfolders and only do operation in first subfolders like below
Folder1 (works)
-folder11 (works)
--files(works)
--folder111 (doesnt work)
-folder12(works)
--files(works)
-folder13(works)
--files(works)
What am i doing wrong?
Here is my code:
btnBasla.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
File dir= new File(Path2.toString());
File files[]=dir.listFiles();
for (File f: files) {
if (f.isDirectory()) {
try {
listDir(f.toString());
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
if(f.getName().lastIndexOf('.')>0) {
int lastIndex = f.getName().lastIndexOf('.');
String str = f.getName().substring(lastIndex);
if(str.equals(".txt") || str.equals(".sub") || str.equals(".srt")) {
try {
String sonuc = islem.koddegıstır(f.getAbsolutePath());
textField.append(sonuc+"\n");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
}
public void listDir (String dir) throws IOException{
File place = new File(dir);
if(place.isDirectory()){
File files[]= place.listFiles();
for (File f:files) {
if (f.isDirectory()) {
listDir(f.getName());
} else {
if(f.getName().lastIndexOf('.')>0) {
int lastIndex = f.getName().lastIndexOf('.');
String str = f.getName().substring(lastIndex);
if(str.equals(".txt") || str.equals(".sub") || str.equals(".srt")) {
String sonuc = islem.koddegıstır(f.getAbsolutePath());
textField.append(sonuc+"\n");
}
}
}
}
}
}
});
Something goes wrong with your function that lists files.
I think you should get all files in sub folders by using this function.
public List<File> listFiles(String dirPath) {
List<File> files = new ArrayList<>();
File dir = new File(dirPath);
if(dir.isDirectory()) {
for(File file : dir.listFiles()) {
if(file.isDirectory()) files.addAll(listFiles(file));
else files.add(file);
}
}
return files;
}
As you can see, this function listing the files recursively.
iRandomXx's answer is correct, it's a recursion problem. I wanted to add to it though if it can be useful to you.
Consider separating the logic a bit more.
1- get all the files with a recursive method to walk them. It looks like you're only interested in files (and not directories). iRandomXx's method will get only the files and leave the directories, making your if-directory check redundant (I removed it).
2- iterate the list and do whatever you need to with each file. If an exception occurs, you should do something useful with it like show a meaningful error message to the user or add it to a list of errors.
btnBasla.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// get all files first
File files[]=listFiles(Path2.toString()); // iRandomX's recursive method
for (File f : files) {
// your validation check for extensions
// modified a bit
try {
String fName = f.getName();
int dotPos = fName.lastIndexOf('.');
if(dotPos > 0) {
String extension = fName.substring(dotPos);
if(VALID_EXTENSIONS.contains(extension)) {
textField.append(islem.koddegıstır(f.getAbsolutePath())+"\n");
}
}
} catch (Exception e) {
// do something useful with the exception, like show the user an error dialog
}
}
}
}
// private class member
private static final List<String> VALID_EXTENSIONS = new ArrayList<>();
// static block to initialize valid extensions
static {
VALID_EXTENSIONS.add(".txt");
VALID_EXTENSIONS.add(".sub");
VALID_EXTENSIONS.add(".srt");
}
// iRandomX's recursive method here

FileSystem Implementation, Recursively listing files

I'm working on implementing the ls method in my program. I need to create a recursive method that will walk through my FileSystem.
Here is my FileSystem implementation right now:
import java.util.ArrayList;
public class FileSystem {
private Directory root;
private Directory wDir;
private ArrayList<File> files = new ArrayList<File>();
// Constructor
public FileSystem() {
}
// Constructor with parameters
public FileSystem(Directory root) {
this.root = root;
wDir = root;
files.add(root);
}
// Returns the FileSystem's files
public ArrayList<File> getFiles() {
return files;
}
// Returns the working directory
public Directory getWDir() {
return wDir;
}
// Sets the working directory
public void setWDir(Directory d) {
wDir = d;
}
// Returns the root file. This will always be / in our program
public File getRoot() {
return root;
}
public File getFile(File f, String name) {
if (f.isDirectory()) {
for (File c : ((Directory) f).getChildren()) {
if (c.getName().equals(name))
return c;
}
}
return null;
}
// Currently only used in cat method, getFile is better
File findFile(File f, String name) {
if (f.getName().equals(name))
return f;
File file = null;
if (f.isDirectory()) {
for (File c : ((Directory) f).getChildren()) {
file = findFile(c, name);
if (file != null)
break;
}
}
return file;
}
// Returns true if file is found
boolean isFile(String name) {
File file = null;
file = getFile(wDir, name);
if (file != null) {
return true;
}
return false;
}
// Creates Directory
public void mkdir(String path) {
files.add(new Directory(path));
int size = files.size();
// Sets the parent
files.get(size - 1).setParent(wDir);
// Sets the child
wDir.addChild(files.get(size - 1));
}
// Changes working directory
public void cd(String s) {
if (s.equals("..")) {
if (wDir != root) {
wDir = wDir.getParent();
}
} else if (s.equals("/")) {
wDir = root;
} else {
wDir = (Directory) getFile(wDir, s);
}
}
// Provides absolute filename
public void pwd() {
if (wDir == root) {
System.out.println("/");
} else {
System.out.println(wDir.getPath());
}
}
// Lists children of current working directory
public void ls() {
ArrayList<File> children = wDir.getChildren();
if (children != null) {
for (int i = 0; i < children.size(); i++) {
String childName = children.get(i).getName();
System.out.print(childName + " ");
}
}
}
// Lists children of file(s) inputted by user
public void ls(File f) {
String name = f.getName();
if (f instanceof TextFile) {
System.out.println(f.getPath());
} else {
ArrayList<File> children = ((Directory) f).getChildren();
if (children != null) {
for (int i = 0; i < children.size(); i++) {
String childName = children.get(i).getName();
System.out.print(childName + " ");
}
}
}
}
// Creates a TextFile or edit's TextFile's content if already exists in the
// tree
public void edit(String name, String content) {
files.add(new TextFile(name, content));
// Setting TextFile parent
files.get(files.size() - 1).setParent(wDir);
// Setting Parent's child
wDir.addChild(files.get(files.size() - 1));
}
// Prints the content of TextFile
public void cat(String name) {
File f = findFile(root, name);
System.out.println(((TextFile) f).getContent());
}
}
As an example of what it needs to do, let's say I have a tree like this:
/
/ \
a b
/ \
x c
/ \
y d
If the user were to enter: ls -r a, my main class would convert that String value using the getFile method, and I would enter that into my recursive function. It would then make use of either ls() or ls(File f), and my main program would output something like this:
a:
x
a/x:
y
a/x/y:
How should I go about creating this method?
Also I should note that I have a Main class, a File class, and a TextFile and Directory class that inherit File.
Any other information that is needed just let me know and I will update this post with it.
You could use something like this:
public void ls(File f) {
System.out.println(f); //or whatever is needed to print the filename
if(f instanceof Directory) {
List<File> fileList = ((Directory)f).getFiles();
//with Java 8
fileList.forEach(subFile -> System.out.println(subFile));
fileList.forEach(subFile -> ls(subFile));
//without Java 8
for(File subFile : fileList) {
System.out.println(subFile);
}
for(File subFile : fileList) {
ls(subFile);
}
System.out.println();
}
}
Basically the first loop is printing all the files in the current directory and the second loop is doing that for all the subdirectories. If the File is not a Directory only it's name is printed. Here I'm assuming that your Directory class has a getFiles() method that returns a List of all Files in the Directory

Search for file of a specific pattern in a directory

In Java, how do I check folders recursively for a file of a specific pattern? I've seen the below code in a lot of posts online:
public static void findFiles() throws IOException {
File dir = new File(".");
FileFilter fileFilter = new WildcardFileFilter("*.txt");
File[] files = dir.listFiles(fileFilter);
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}
}
In my application, I basically need to check files matching *.txt in a user's home directory.
Since the path will vary for each user, how do I use this code to search for a file matching a pattern anywhere on the filesystem?
You could actually simply use:
final File dir = new File(System.getProperty("user.home"));
This would set the dir to your user's home directory. From there, you simply have to list all the .txt files, not recursively ;)
However, if you still want to list all files from a directory, recursively, you can use the following method:
public static List<File> walk(final File root, final String extension) {
final File[] list = root.listFiles();
if (list == null) {
return Collections.EMPTY_LIST;
}
final List<File> res = new ArrayList<>();
for (final File f : list) {
if (f.isDirectory()) {
res.addAll(walk(f, extension));
} else {
if (f.getName().endsWith(extension)) {
res.add(f);
}
}
}
return res;
}
You can use it as follows:
public static void main(final String[] args) {
for (final File file : walk(new File("/home/user3751169"), ".txt")) {
System.out.println(file.getAbsolutePath());
}
}
On the other hand, if you want to look only for the files in the home directory of the current user, you should remove the recursive call to walk():
public static List<File> walk(final File root, final String extension) {
final File[] list = root.listFiles();
if (list == null) {
return Collections.EMPTY_LIST;
}
final List<File> res = new ArrayList<>();
for (final File f : list) {
if (f.isFile() && f.getName().endsWith(extension)) {
res.add(f);
}
}
return res;
}

How to return File[] array after adding all files to it

I am new to this group. Please suggest how to return File[] array as my code below is giving NullPointerException when I am trying to add all text files from "D:\" to File[] array, as I want to return all text files as an File[] array which will be used in another method to read all text files.
File[] allFiles;
int i = 0;
public File[] findFiles(File source) {
FileFilter filter = new FileFilter() {
#Override
public boolean accept(File pathname) {
// TODO Auto-generated method stub
if (!pathname.isHidden()) {
return true;
}
return false;
}
};
File[] list = source.listFiles(filter);
if (list != null) {
for (File f : list) {
if (f.isDirectory()) {
findFiles(f);
}
if (f.getName().contains("txt")) {
System.out.println(f.getAbsolutePath());
allFiles[i] = f; // it is giving nullpointerexception
i++;
}
}
}
return allFiles; // want to return this to another method
}
The main problem you're having is you've not initialized allFiles before using it...
File[] list = source.listFiles(filter);
if (list != null) {
for (File f : list) {
//...
// still null
allFiles[i] = f; // it is giving nullpointerexception
You could use allFiles = new File[list.length], but the problem here is you could end up with null elements in the list, as you are filtering out elements...
Instead, you could use your FileFilter, that's what it's there for...for example...
public File[] findFiles(File source) {
FileFilter filter = new FileFilter() {
#Override
public boolean accept(File pathname) {
return !pathname.isHidden() &&
pathname.getName().toLowerCase().endsWith(".txt");
}
};
File[] list = source.listFiles(filter);
return list;
}
Basically, what this does is checks to see if the file is not hidden and if its name ends with .txt, as an example...
Updated
Because you're doing a recursive look up, you really need some way to add new files to your array and grow it dynamically.
While you can do this with plain old arrays, some kind of List would be much easier, for example...
The following uses the FileFilter to find all non-hidden files that directories or end in .txt
It then sorts the resulting list of files, so that the "files" appear first and the "directories" or sorted to the bottom, this is a nit pick, but ensure a certain order of files in the list.
It then processes the file list, adding the "files" to the List and recurisivly scanning the "directories", adding the results to the List...
public static File[] findFiles(File source) {
FileFilter filter = new FileFilter() {
#Override
public boolean accept(File pathname) {
return !pathname.isHidden() &&
(pathname.isDirectory() ||
pathname.getName().toLowerCase().endsWith(".txt"));
}
};
File[] files = source.listFiles(filter);
Arrays.sort(files, new Comparator<File>() {
#Override
public int compare(File o1, File o2) {
int compare = 0;
if (o1.isDirectory() && o2.isDirectory()) {
compare = 0;
} else if (o1.isFile()) {
compare = -1;
} else {
compare = 1;
}
return compare;
}
});
List<File> fileList = new ArrayList<>(25);
for (File file : files) {
if (file.isFile()) {
fileList.add(file);
} else {
fileList.addAll(Arrays.asList(findFiles(file)));
}
}
return fileList.toArray(new File[fileList.size()]);
}
As an example...
Very simple, just initialize the allFiles array
File[] list = source.listFiles(filter);
// initialize here because we know the size now.
allFiles = new File[list.length];
Define the File[] allFiles,Like -
File[] allFiles = new File[list.length];
Alternatively you can use List instead of Array, which is dynamic array(not fixed size).
Initialization -
List<File> allFiles = new ArrayList<File>();
Adding element -
allFiles.add(f);
FileFilter filter = new FileFilter() {
#Override
public boolean accept(File pathname) {
return !pathname.isHidden() &&
pathname.getName().toLowerCase().endsWith(".txt");
}
};
File[] files = f.listFiles(filter);
for (File file : files) {
if (file.isDirectory()) {
System.out.print("is a directory");
} else {
System.out.print("is a file");
}
System.out.println(file.getCanonicalPath());
}

Categories

Resources