Traversing a directory for a specific folder - java

enter code hereI wrote the following code which searches a folder directory recursively to find a specific folder.
The program is supposed to do check the folder name and if the folder name is "src", then it should go into that folder to get all the files. Currently the program is getting all the files from all the directories.
public class Main {
public static void main(String[] args) {
File fileObject = new File("C:\\Users\\lizzie\\Documents\\");
recursiveTraversal(fileObject);
}
public static void recursiveTraversal(File fileObject)
{
if (fileObject.isDirectory())
{
File allFiles[] = fileObject.listFiles();
for(File aFile : allFiles){
recursiveTraversal(aFile);
}
}
else if (fileObject.isFile())
{
System.out.println(fileObject.getAbsolutePath());
}
}
}
when I check if a certain folder is a directory, I added the following constraint but that didn't help.
if (fileObject.isDirectory() && fileObject.getName().equals("src"))`
Please let me know what I can do to improve my code. Anything will be appreciated.
Thanks

If you look at your if-else inside recursiveTraversal, you'll see that you're printing anything that isn't a directory, regardless of where it is. Here's a fix:
public class Main {
public static void main(String[] args) {
File fileObject = new File("C:\\Users\\lizzie\\Documents\\");
recursiveSearch(fileObject);
}
public static void recursiveSearch(File fileObject) {
if (fileObject.isDirectory()) {
if (fileObject.getName().equals("src")) {
recursivePrint(fileObject);
} else {
File allFiles[] = fileObject.listFiles();
for(File aFile : allFiles){
recursiveSearch(aFile);
}
}
}
// ignore non-directory objects during search
}
public static void recursivePrint(File fileObject)
{
if (fileObject.isDirectory())
{
File allFiles[] = fileObject.listFiles();
for(File aFile : allFiles){
recursivePrint(aFile);
}
}
else if (fileObject.isFile())
{
System.out.println(fileObject.getAbsolutePath());
}
}
}
This will print all the files recursively of any directory named src.

What you need to do is put the constraint on what's being printed, not what's being traversed. As you've noticed, the traversal is working fine, since it gets all files in all subfolders.
If you want to print only the filenames inside of the "src" directory (not in subdirectories), then you can do...
...
else if (fileObject.isFile() && fileObject.getParent().getName().equals("src")
{
System.out.println(fileObject.getAbsolutePath());
}
...
If you want to print what's in the "src" directory, and all subdirectories, then you'll need to break your algorithm into two parts
find the "src" folder, then
use your current algorithm to print everything in all directories from there and lower

Instead of checking for .equals() on the name, check if the name contains "src" using either fileObject.getName().contains(StringBuffer) or fileObject.getName().indexOf("src") != -1

Related

How to rename folder even if this target folder has already exist?

How to rename folder even if the target folder with same name has already existed in the directory.
I have tried the method renameTo of class File,but it does not work.
For example:
/root
/a
/b
I want to rename folder b with the name of folder a, actually the folder a will be replaced,yes,that's what I want.
You need to first delete everything in 'a' or move/rename it to something else.
You can delete it with Apache's recurrsive deleteDictionary function. This gets every file in the aFolder and deletes it, then deletes the folder itself.
FileUtils.deleteDirectory(aFolder);
Then, you can use #renameTo
bFolder.renameTo(aFolder);
In Java 7 and above you can turn to Files for delete and move.
In your case, you can achieve it as follows:
public class HelloWord {
public static void main(String... args) throws Exception {
Path targetPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/resources/").concat("a"));
Path thePath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/resources/").concat("b"));
if (Files.exists(targetPath)) { // if the target folder exists, delete it first;
deleteFolder(targetPath);
}
Files.move(thePath, targetPath);
}
private static void deleteFolder(Path path) {
try {
if (Files.isRegularFile(path)) { // delete regular file directly;
Files.delete(path);
return ;
}
try (Stream<Path> paths = Files.walk(path)) {
paths.filter(p -> p.compareTo(path) != 0).forEach(p -> deleteFolder(p)); // delete all the children folders or files;
Files.delete(path); // delete the folder itself;
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
}
My local test
The structure of the folder for my local test is as follows:
The result:
The solution uses java.nio.file.Files class's move static method.
import java.nio.file.*;
import java.io.IOException;
import java.nio.file.attribute.*;
import java.util.*;
import java.util.stream.*;
public class FilesMoveExample {
public static void main (String [] args)
throws IOException {
Path srcePath = Paths.get("C:\\java-nio2\\folder1");
Path targetPath = Paths.get("C:\\java-nio2\\folder2");
Files.move(srcePath, targetPath); // NOTE: Statement A
}
}
Assume folder1 is source directory and contains multiple sub-directories and files.
Scenario 1:
'Statement A' used as it is.
Source folder1 exists and the target folder2 does not exist.
On running the code, folder1 is renamed to folder2. The folder1's file tree is moved to folder2.
Scenario 2:
'Statement A' modified to: Files.move(srcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
Source folder1 and the target folder2 (an empty directory) exists.
On running the code, the target folder2 is replaced with folder1 (and renamed to folder2). The folder1's file tree is moved to folder2.
Scenario 3:
'Statement A' modified to: Files.move(srcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
Source folder1 and the target folder2 (a non-empty directory) exists.
On running the code, throws DirectoryNotEmptyException.
In this scenario 3 the target directory needs to be empty for the move to complete successfully. So, delete the target directory recursively using one of the following methods, and perform the move. The first uses Java 7 and the next uses Java 8:
private static void deleteUsingWalkFileTree(Path start)
throws IOException {
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path dir, IOException e)
throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
} else {
throw e;
}
}
});
}
private static void deleteUsingWalk(Path start )
throws IOException {
List<Path> files = Files.walk(start)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
for (Path p : files) {
Files.delete(p);
}
}

isDirectory() method returning 'false' when invoked on java package 'com'

I did this simple experiment to list all files/directory in a parent directory.
Did this by making a java project in eclipse by name 'JavaProject' and a class 'Temp.java' under src/com. Code is as below:
public class Temp {
public static void main(String[] args) {
search("../JavaProject");
}
public static void search(String dName) {
String[] files = new String[100];
File search = new File(dName); // make file object
if (!search.isDirectory()) {
return;
}
files = search.list(); // create the list
for (String fn : files) {// iterate through it
System.out.print(" " + fn);
File temp = new File(fn);
if (temp.isDirectory()) {
search(fn);
}
System.out.println();
}
}
}
The file structure is as below :
JavaProject(dir)
.classpath(file)
.project(file)
.settings(dir)
org.eclipse.jdt.core.prefs(file)
bin(dir)
com(file)
Temp.class(file)
src(dir)
com(dir)
Temp.java(file)
When I run the above program, it gives the following output:
.classpath
.project
.settings org.eclipse.jdt.core.prefs
bin com
src com
I cant understand why it does not print the .java file and .class file inside the com folders.
When I try debugging then the file object on 'com' returns 'false' for both isDirectory() and isFile() methods.
When it gets to the 'com' directory your code is doing:
File temp = new File("com");
Since you have not specified any path this will be taken to be relative to the current directory which is not the directory containing 'com'.
You should use something like:
File temp = new File(parent, fn);
where parent is the File object for the parent directory.
You can use listFiles() instead of list(). See below example:
public class Program {
public static void main(String args[]) throws IOException {
search(new File("."), 0);
}
public static void search(File file, int level) {
if (!file.isDirectory()) {
return;
}
for (File f : file.listFiles()) {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println(f.getName());
if (f.isDirectory()) {
search(f, ++level);
}
}
}
}

How to check if a folder exists?

I am playing a bit with the new Java 7 IO features. Actually I am trying to retrieve all the XML files in a folder. However this throws an exception when the folder does not exist. How can I check if the folder exists using the new IO?
public UpdateHandler(String release) {
log.info("searching for configuration files in folder " + release);
Path releaseFolder = Paths.get(release);
try(DirectoryStream<Path> stream = Files.newDirectoryStream(releaseFolder, "*.xml")){
for (Path entry: stream){
log.info("working on file " + entry.getFileName());
}
}
catch (IOException e){
log.error("error while retrieving update configuration files " + e.getMessage());
}
}
Using java.nio.file.Files:
Path path = ...;
if (Files.exists(path)) {
// ...
}
You can optionally pass this method LinkOption values:
if (Files.exists(path, LinkOption.NOFOLLOW_LINKS)) {
There's also a method notExists:
if (Files.notExists(path)) {
Quite simple:
new File("/Path/To/File/or/Directory").exists();
And if you want to be certain it is a directory:
File f = new File("/Path/To/File/or/Directory");
if (f.exists() && f.isDirectory()) {
...
}
To check if a directory exists with the new IO:
if (Files.isDirectory(Paths.get("directory"))) {
...
}
isDirectory returns true if the file is a directory; false if the file does not exist, is not a directory, or it cannot be determined if the file is a directory or not.
See: documentation.
Generate a file from the string of your folder directory
String path="Folder directory";
File file = new File(path);
and use method exist.
If you want to generate the folder you sould use mkdir()
if (!file.exists()) {
System.out.print("No Folder");
file.mkdir();
System.out.print("Folder created");
}
You need to transform your Path into a File and test for existence:
for(Path entry: stream){
if(entry.toFile().exists()){
log.info("working on file " + entry.getFileName());
}
}
There is no need to separately call the exists() method, as isDirectory() implicitly checks whether the directory exists or not.
import java.io.File;
import java.nio.file.Paths;
public class Test
{
public static void main(String[] args)
{
File file = new File("C:\\Temp");
System.out.println("File Folder Exist" + isFileDirectoryExists(file));
System.out.println("Directory Exists" + isDirectoryExists("C:\\Temp"));
}
public static boolean isFileDirectoryExists(File file)
{
if (file.exists())
{
return true;
}
return false;
}
public static boolean isDirectoryExists(String directoryPath)
{
if (!Paths.get(directoryPath).toFile().isDirectory())
{
return false;
}
return true;
}
}
We can check files and thire Folders.
import java.io.*;
public class fileCheck
{
public static void main(String arg[])
{
File f = new File("C:/AMD");
if (f.exists() && f.isDirectory()) {
System.out.println("Exists");
//if the file is present then it will show the msg
}
else{
System.out.println("NOT Exists");
//if the file is Not present then it will show the msg
}
}
}
File sourceLoc=new File("/a/b/c/folderName");
boolean isFolderExisted=false;
sourceLoc.exists()==true?sourceLoc.isDirectory()==true?isFolderExisted=true:isFolderExisted=false:isFolderExisted=false;
From SonarLint, if you already have the path, use path.toFile().exists() instead of Files.exists for better performance.
The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist.
The same goes for Files.notExists, Files.isDirectory and Files.isRegularFile.
Noncompliant Code Example:
Path myPath;
if(java.nio.Files.exists(myPath)) { // Noncompliant
// do something
}
Compliant Solution:
Path myPath;
if(myPath.toFile().exists())) {
// do something
}

Getting multiple java files directory

I need go through a package with sub-packages that contains some java class file. Can someone teach me how to get all those java class file directories and store it in a String array?
public void getClassArray(File dir, List<String> results) {
File[] filesInDir = dir.listFiles();
for (File file : filesInDir) {
if (file.isDirectory()) {
getClassArray(file, results);
}
else if (file.getName().endsWith(".class")) {
results.add(file.getName());
}
}
}
can this work?
The other post will give you all the class file name the below code snippet will give you all the folders which have .class files within
public void getClassFolders(File file, List<String> fileNames){
for (File child : file.listFiles()) {
if(child.isDirectory()){
getClassFolders(child, fileNames);
} else if(child.getName().endsWith(".class")){
fileNames.add(file.getName());
}
}
}

Java - Strange directory problem?

When I run a class with the following code:
public static void main(String[] args)
{
createDuplicateStructure("in", "out");
}
public static void createDuplicateStructure(String path_start, String path_result)
{
File start = new File(path_start);
File result = new File(path_result);
duplicateDirectoryStructure(start, result);
}
public static void duplicateDirectoryStructure(File start_dir, File result_dir)
{
//FileFilter used by listFiles(filter) - to make sure they are dirs
FileFilter dirs_only = new FileFilter()
{
public boolean accept(File file){ return file.isDirectory();}
};
File[] dir_contents = start_dir.listFiles(dirs_only);
for(File dir : dir_contents)
{
File duplicate = new File(result_dir.getPath(), dir.getName());
if(dir.mkdir())
{
duplicateDirectoryStructure(dir, duplicate);
}
else
{
System.out.println("ERROR: Unable to create dir! (" + duplicate.getPath() + ")");
}
}
}
I get this in the console:
Error: Unable to create dir! (out/a)
Error: Unable to create dir! (out/a)
Error: Unable to create dir! (out/a)
The directory "out" is in the same directory as the .jar.
There is a directory "in" which contains "a", "b", and "c" directories (for testing).
Any ideas why this is not working?
Thanks!
You should replace dir.mkdir() with duplicate.mkdir() because dir is the already existing source directory.
dir.mkdir() only returns true the directory was actually created. Try doing
if(dir.mkdir() || dir.exists())
The line
`if(dir.mkdir())`
is trying to create the existing directory structure
if you change it to
if(duplicate.mkdir())
you get another problem where it tries to create the a subdirectory under out which does not exist yet.
So change it to
if(duplicate.mkdirs())
which will create the directory structure, or create the out directory before you start your loop.

Categories

Resources