Java recursion print directory subdirectory files - java

I'm trying to loop through a folder and list all files with a specific file ending. I'm trying to solve this problem with a recursive method but I'm not getting anywhere.
private int counter = 0;
public void printAllJavaFiles(File directory) {
printFile(directory);
File[] subDirectories = directory.listFiles();
for (File file : subDirectories) {
printAllJavaFiles(file);
}
}
private void printFile(File file) {
// Get file extension
String fileExtension = "";
int i = file.getName().lastIndexOf('.');
if (i >= 0) {
fileExtension = file.getName().substring(i + 1);
}
if (fileExtension.equals("java")) {
System.out.println("File: " + file.getName() + " Size: " + file.length());
}
}
Any suggestions? I really have no idea how to go up and down in the directory structure. It just enters the first folder and once it's done listing it's files it throws a nullpointerexception.

You should use the File.isDirectory() method. Like this:
public void printAllJavaFiles(File directory) {
if (directory.isDirectory()) {
File[] subDirectories = directory.listFiles();
for (File file : subDirectories) {
printAllJavaFiles(file);
}
}else {
printFile(directory);
}
}
Documentation on that method here: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#isDirectory()
The idea is that for every file you check if it is a folder, if so, make the recursive call. If not, simply print the file.

Related

How do I conditionally get code to loop back to specific point in code in java?

I am creating an application that automatically sorts and organizes files into a database​. I have written my code to read files within the imported folder one at a time, and process them into the DB. However, I am having trouble looping this process, so that I can process files that are nested in any amount of folders within the original folder that the user wants to input.
I simply need to instruct my program to go back to a specific part of my code and start running from there again.
Another possible way to solve this issue would be to create a way to list out all of the individual files within folder (including all the files within subfolders), and I could easily fit that into my program too.
I tried using labeled continue, return, and break keywords based off of an answer I got online, but I never expected those to succeed in looping my code back to a specific spot.
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFiles(null);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.showOpenDialog(null);
//Getting file paths from within folder
File f = chooser.getSelectedFile();
String file = f.getAbsolutePath();
if (f.isDirectory()) {
//Need to loop back to here
File folder = new File(file);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isDirectory()) {
//Code here is run if there is a folder within a folder. I tested it too
//I want the code here to loop back above where it says "Need to loop back to here"
}
if (listOfFiles[i].isFile()) { //Once I list the files from within the folder, their information gets assigned variable here, and the rest of my program sorts it and saves it to DB accordingly.
//Everything below here is not important, but it might be helpful to see what happens each file with the folders.
System.out.println(listOfFiles[i]);
String filename = (listOfFiles[i].getName()); //For Files
Long filemodified = (listOfFiles[i].lastModified());
String filepath = (listOfFiles[i].getAbsolutePath());
Long filesizeraw = (listOfFiles[i].length());
long filehashcode = (listOfFiles[i].hashCode());
String fileparent = (listOfFiles[i].getParent());
Currently, there is no error message. It would process any individual files directly in the imported file (not nested in any folder within the folder), but wouldn't get to any of the files that are in folders within folders.
Another possible way to solve this issue would be to create a way to list out all of the individual files within folder (including all the files within subfolders), and I could easily fit that into my program too
Although this doesn't do the SQLite inserts, the following class extracts a list (of File objects) the files (thus file name and path are available via the File object).
public class FTS {
private ArrayList<File> mFileList; //Resultant list of Files extracted
private String mBaseDirectory; // The Directory to search
private long mSubDirectoryCount; // The count of the subdirectories
//Constructor
public FTS(String directory) {
this.mBaseDirectory = directory;
this.mSubDirectoryCount = 0;
buildFileListing(this.mBaseDirectory);
}
//
private void buildFileListing(String directory) {
// Initialise the ArrayList for the result
if (mFileList == null) {
mFileList = new ArrayList(){};
}
//Get the File (directory to process)
File dir = new File(directory);
// Get the List of the Directories contents
String[] filelist = dir.list();
// If empty (null) then return
if (filelist == null) {
return;
}
// Loop through the directory list
for (String s: filelist) {
//get the current list item as a file
File f = new File(dir.getAbsolutePath() + File.separator + s);
// is it a file or directory?
if (f.isFile() && !f.isDirectory()) {
this.mFileList.add(f); // If a file then add the file to the extracted list
} else {
// If a directory then increment the count of the subdirectories processed
mSubDirectoryCount++;
// and then recursively call this method to process the directory
buildFileListing(f.getAbsolutePath());
}
}
}
// return the list of extracted files
public ArrayList<File> getFileList() {
return this.mFileList;
}
// return the number of sub-directories processed
public long getSubDirectoryCount() {
return this.mSubDirectoryCount;
}
}
An example usage of the above is :-
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
FTS fileTreeSearch;
String BaseDirectory = "E:" + File.separator;
List<File> files = (fileTreeSearch = new FTS(BaseDirectory)).getFileList();
System.out.println("Extracted " + String.valueOf(files.size()) + " files, from " + String.valueOf(fileTreeSearch.getSubDirectoryCount()) + " sub-directories of " + BaseDirectory);
/* this commented out code would process all the extracted files
for (File f: files) {
System.out.println("File is " + f.getName() + "\t\t path " + f.getAbsolutePath());
}
*/
}
}
Example output from running the above :-
Extracted 186893 files, from 54006 sub-directories of E:\

List of files inside a zip folder and its subfolder

I am looking a way to get the list of files inside a zip file. I created a method to get the list of files inside a directory but I am also looking a way to get files inside a zip as well instead of showing just zip file.
here is my method:
public ArrayList<String> listFiles(File f, String min, String max) {
try {
// parse input strings into date format
Date minDate = sdf.parse(min);
Date maxDate = sdf.parse(max);
//
File[] list = f.listFiles();
for (File file : list) {
double bytes = file.length();
double kilobytes = (bytes / 1024);
if (file.isFile()) {
String fileDateString = sdf.format(file.lastModified());
Date fileDate = sdf.parse(fileDateString);
if (fileDate.after(minDate) && fileDate.before(maxDate)) {
lss.add("'" + file.getAbsolutePath() +
"'" + " Size KB:" + kilobytes + " Last Modified: " +
sdf.format(file.lastModified()));
}
} else if (file.isDirectory()) {
listFiles(file.getAbsoluteFile(), min, max);
}
}
} catch (Exception e) {
e.getMessage();
}
return lss;
}
After having searched for a better answer for a while, I finally found a better way to do this. You can actually do the same thing in a more generic way using the Java NIO API (Since Java 7).
// this is the URI of the Zip file itself
URI zipUri = ...;
FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.emptyMap());
// The path within the zip file you want to start from
Path root = zipFs.getPath("/");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
// You can do anything you want with the path here
System.out.println(path);
// the BasicFileAttributes object has lots of useful meta data
// like file size, last modified date, etc...
return FileVisitResult.CONTINUE;
}
// The FileVisitor interface has more methods that
// are useful for handling directories.
});
This approach has the advantage that you can travers ANY file system this way: your normal windows or Unix filesystem, the file system contain contained within a zip or a jar, or any other really.
You can then trivially read the contents of any Path via the Files class, using methods like Files.copy(), File.readAllLines(), File.readAllBytes(), etc...
You can use ZipFile.entries() method to read the list of files via iteration as below:
File[] fList = directory.listFiles();
for (File file : fList)
{
ZipFile myZipFile = new ZipFile(fList.getName());
Enumeration zipEntries = myZipFile.entries();
while (zipEntries.hasMoreElements())
{
System.out.println(((ZipEntry) zipEntries.nextElement()).getName());
// you can do what ever you want on each zip file
}
}

Change files names in parent and child directories

I am a beginner in Java trying to work with Files and Directories. I wanted to create a program where I could change file names automatically while searching through all the child directories for file names that are not valid. I am actually trying to load a huge amount of files on to a server but the server settings do not allow file names containing special characters. To start with I was able to write the code where if I pass the path to a directory it renames all the files with invalid names in that directory:
public class reNaming {
public static String baseLoc = "C:/Users/Developer/Desktop/.../Data Cleanup";
public static void main(String[] args) {
//LinkedList<File> fileList = new LinkedList<File>();
File obj = new File(baseLoc);
int count = 0;
for (File file: obj.listFiles())
{
String origName = file.getName();
if (origName.contains("&") || origName.contains("#") || origName.contains("#"))
{
System.out.println("Original name: "+origName);
origName = origName.replaceAll("&", "_and_");
origName = origName.replaceAll("#", "_at_");
String newName = origName.replaceAll("#", "_");
System.out.println("New Name: "+newName);
String newLoc = baseLoc+"/"+newName;
File newFile = new File(newLoc);
System.out.println(file.renameTo(newFile));
count++;
}
}
}
}
Now I want to do the same but only this time I want all the files to be reNamed even in the child directories. Can somebody please guide me how I can achieve that?
Recursion is your friend
/**Removes 'invalid' characters (&,#,#) from pathnames in the given folder, and subfolders, and returns the number of files renamed*/
public int renameDirectory(File base){
//LinkedList<File> fileList = new LinkedList<File>();
int count=0;//count the renamed files in this directory + its sub. You wanted to do this?
//Process each file in this folder.
for (File file: base.listFiles()){
String origName = file.getName();
File resultFile=file;
if (origName.contains("&") || origName.contains("#") || origName.contains("#")){
//I would replace the if statement with origName.matches(".*[&##].*") or similar, shorter but more error prone.
System.out.println("Original name: "+origName);
origName = origName.replaceAll("&", "_and_");
origName = origName.replaceAll("#", "_at_");
String newName = origName.replaceAll("#", "_");
System.out.println("New Name: "+newName);
String newLoc = baseLoc+File.separator+newName;//having "/" hardcoded is not cross-platform.
File newFile = new File(newLoc);
System.out.println(file.renameTo(newFile));
count++;
resultFile=newFile;//not sure if you could do file=newFile, tired
}
//if this 'file' in the base folder is a directory, process the directory
if(resultFile.isDirectory()){//or similar function
count+=renameDirectory(resultFile);
}
}
return count;
}
Move the code you have to a utility method (e.g. public void renameAll(File f){}). Have a condition that checks if the file is a directory and recursively call your method with it's contents. After that do what you are currently doing.
public void renameAll(File[] files){
for(File f: files){
if(f.isDirectory){
renameAll(f.listFiles());
}
rename(f);
}
}
public void rename(File f){ }

Get access to all files in "recent documents" folder

I want to get a list of all files recently open or created, i.e. all the files in the Windows "recent folder" .
I can't find any solutions, I tried shgetfolderpath, windows registry but nothing worked. How can I get access to all files in the recent folder using Java?
Try this code in java :
File file = new File("Windows/Recent/Folder/Path");
if (file.exists() && file.isDirectory()) {
File[] listFiles = file.listFiles();
for (File files : listFiles) {
if(files.isDirectory()) {
System.out.println(files.getAbsolutePath() + " - Directory");
}else {
System.out.println(files.getAbsolutePath() + " - File");
}
}
}
Hope this will help you, try this out:
import java.io.File;
public class ListFiles
{
public static void main(String[] args)
{
// Directory path here
String path = "F:\\Book"; // the directory you want to search
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
System.out.println(files);// with out printing you can add the names of file in array
}
}
}
}

Java: How to read directory folder, count and display no of files and copy to another folder?

I have to read a folder, count the number of files in the folder (can be of any type), display the number of files and then copy all the files to another folder (specified).
How would I proceed?
i Have to read a folder, count the number of files in the folder (can
be of any type) display the number of files
You can find all of this functionality in the javadocs for java.io.File
and then copy all the files to another folder (specified)
This is a bit more tricky. Read: Java Tutorial > Reading, Writing and Creating of Files
(note that the mechanisms described there are only available in Java 7 or later. If Java 7 is not an option, refer to one of many previous similar questions, e.g. this one: Fastest way to write to file? )
you have all the sample code here :
http://www.exampledepot.com
http://www.exampledepot.com/egs/java.io/GetFiles.html
File dir = new File("directoryName");
String[] children = dir.list();
if (children == null) {
// Either dir does not exist or is not a directory
} else {
for (int i=0; i<children.length; i++) {
// Get filename of file or directory
String filename = children[i];
}
}
// It is also possible to filter the list of returned files.
// This example does not return any files that start with `.'.
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return !name.startsWith(".");
}
};
children = dir.list(filter);
// The list of files can also be retrieved as File objects
File[] files = dir.listFiles();
// This filter only returns directories
FileFilter fileFilter = new FileFilter() {
public boolean accept(File file) {
return file.isDirectory();
}
};
files = dir.listFiles(fileFilter);
The copying http://www.exampledepot.com/egs/java.io/CopyDir.html :
// Copies all files under srcDir to dstDir.
// If dstDir does not exist, it will be created.
public void copyDirectory(File srcDir, File dstDir) throws IOException {
if (srcDir.isDirectory()) {
if (!dstDir.exists()) {
dstDir.mkdir();
}
String[] children = srcDir.list();
for (int i=0; i<children.length; i++) {
copyDirectory(new File(srcDir, children[i]),
new File(dstDir, children[i]));
}
} else {
// This method is implemented in Copying a File
copyFile(srcDir, dstDir);
}
}
However is very easy to gooole for this stuff :)
I know this is too late but below code worked for me. It basically iterates through each file in directory, if found file is a directory then it makes recursive call. It only gives files count in a directory.
public static int noOfFilesInDirectory(File directory) {
int noOfFiles = 0;
for (File file : directory.listFiles()) {
if (file.isFile()) {
noOfFiles++;
}
if (file.isDirectory()) {
noOfFiles += noOfFilesInDirectory(file);
}
}
return noOfFiles;
}

Categories

Resources