If you have the directory name in myDirectoryPath,

import java.io.File;
...
  File dir = new File(myDirectoryPath);
  File[] directoryListing = dir.listFiles();
  if (directoryListing != null) {
    for (File child : directoryListing) {
      // Do something with child
    }
  } else {
    // Handle the case where dir is not really a directory.
    // Checking dir.isDirectory() above would not be sufficient
    // to avoid race conditions with another process that deletes
    // directories.
  }
Answer from Mike Samuel on Stack Overflow
Top answer
1 of 1
2

FolderProcessor

if (inputfile.isDirectory()) {
    processFolder(filePath, outputPath + filename);
}

This is why you're not seeing any benefits from parallelism; you're processing subfolders within the same thread! But even so, you'd be making a new ExecutorService each invocation; pool should be a class-level field:

private final ExecutorService pool;

public FolderProcessor(ExecutorService pool){
    this.pool = pool;
}

After running some tests, I noticed that your path resolution is broken; the path separator isn't being added for subpaths! You can use all the operating system's rules by switching to Paths:

String filePath = inputFolder.toPath().resolve(filename).toString();

Some quick cleanup and a change to lambda notation (Java 8 is so much cleaner):

class FolderProcessor{
    private static final Logger log = Logger.getGlobal();
    private final ExecutorService pool;

    public FolderProcessor(ExecutorService pool){
        this.pool = pool;
    }

    void processFolder(String inputPath, String outputPath){
        File inputFolder = new File(inputPath);

        for (String filename : inputFolder.list()) {
            String filePath = inputFolder.toPath().resolve(filename).toString();
            String writeTo = new File(outputPath).toPath().resolve(filename).toString();
            if (new File(filePath).isDirectory()) {
                pool.execute(()->processFolder(filePath, writeTo));
            } else {
                pool.execute(()->{
                    log.info("Start processing " + filePath);
                    DocumentWriter.write(filePath, writeTo);
                });
            }
        }
    }
}

Note: My IDE warns me that inputFolder.list() could throw a NullPointerException if the File isn't a directory. While your current usage ensures that it is, you may want to put in a check down the line.

DocumentWriter

Since we're missing the meat of the method (the contents of the for loop), it's hard to make too many recommendations. I am concerned with the shift in naming convention (Java uses camelCase), and the lack of checking for errors in file creation. Also, you create a file and discard it as soon as you've made your checks, when you could save the FileWriter some work by passing it along.

After some cleanup:

class DocumentWriter{
    private static final Logger log = Logger.getGlobal();

    public static void write(String inputPath, String outputPath) {
        try {
            File outputFile = new File(outputPath);
            if(outputFile.getParentFile().mkdirs()){
                outputFile.createNewFile();
                FileWriter outputWriter = new FileWriter(outputFile);

                List<Document> docs = DocProcessor.processDocs(inputPath);
                for(Document doc : docs){
                    // Missing code
                }
            }else{
                // You may want to log this
                log.config("File could not be created: " + outputPath);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

DocProcessor

I assumed you wanted the typo fixed. There's not much else to say about this class, since all the logic is either tied up in a class we can't see (TextThread) or omitted. I will say that if you're running this method in parallel, you're going to be creating an ExecutorService for each invocation, possibly creating hundreds of threads. A shared ExecutorService, (could be static, but preferably a final instance variable) would be a better solution.

Other Notes

You probably want to use Executors.newWorkStealingPool(10) since it keeps the threads active while waiting for I/O operations, which will give you better performance. newFixedThreadPool(10) tends to work better for CPU-intensive operations as opposed to I/O-intensive operations.

Discussions

java - Process files in directories and sub-directories concurrently - Stack Overflow
Using a fixed-size thread pool is also problematic in case we have a many sub-directories What is the best way for using threads here in order to improve performance? ... The time in which you can crawl folders/process files also largely depends on the speed of the drive in the server/computer. More on stackoverflow.com
🌐 stackoverflow.com
October 23, 2018
java - Process incoming files in a directory - Stack Overflow
I want to make a Java program that monitors a directory continuously for a new file, and if a new file arrives, process it and then delete it. What is the best way to do this? More on stackoverflow.com
🌐 stackoverflow.com
July 1, 2010
Hot to set the working directory of a process in Java - Stack Overflow
but every time I launch it, the exe attempts to run but fails to because the current directory is wrong and it can't properly access the required files. ... Here's a little more about whats going on... I have x amount of client folders, each contains an executable file that needs to be started ... More on stackoverflow.com
🌐 stackoverflow.com
May 23, 2017
java - execute file from defined directory with Runtime.getRuntime().exec - Stack Overflow
The problem with cd somewhere is that the directory is changed for a different Process so the second call to exec in a new Process does not see the change. ... File dir = new File("C:/Users/username/Desktop/Sample"); String cmd = "java -jar BatchSample.jar"; Process process = Runtime.getRu... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Tutorialspoint
tutorialspoint.com › java › lang › processbuilder_directory_file.htm
Java ProcessBuilder Directory and File Management
The Java ProcessBuilder directory(File directory) method sets this process builder's working directory. Subprocesses subsequently started by this object's start() method will use this as their working directory.
🌐
javaspring
javaspring.net › blog › java-read-all-files-in-a-directory
Java: Reading All Files in a Directory — javaspring.net
In this blog, we have explored different ways to read all files in a directory using Java. We started by discussing the fundamental concepts of the File class and Java NIO. We then looked at usage methods, common practices such as filtering files by extension and recursive directory traversal, and best practices for exception handling and resource management. By understanding these concepts and techniques, you can efficiently read and process files in your Java applications.
🌐
Stack Overflow
stackoverflow.com › questions › 39029437 › hot-to-set-the-working-directory-of-a-process-in-java
Hot to set the working directory of a process in Java - Stack Overflow
May 23, 2017 - I am trying to set the working directory of a process that will be running an exe. ... public Process launchClient() throws IOException { File pathToExecutable = new File(currentAccount.getAbsoluteFile()+"/Release", "TuringBot.exe"); System.out.println(pathToExecutable); ProcessBuilder builder = new ProcessBuilder(pathToExecutable.getAbsolutePath()); builder.directory( new File( currentAccount, "Release" )); // this is where you set the root folder for the executable to run with System.out.println("Working Directory = " + System.getProperty("user.dir")); return builder.start(); }
Find elsewhere
Top answer
1 of 7
3

Are you looking for something like this?

System.out.println("Current working directory: " + System.getProperty("user.dir"));
System.out.println("Changing working directory...");
// changing the current working directory
System.setProperty("user.dir", System.getProperty("user.dir") + "/test/");

// print the new working directory path
System.out.println("Current working directory: " + System.getProperty("user.dir"));

// create a new file in the current working directory
File file = new File(System.getProperty("user.dir"), "test.txt");

if (file.createNewFile()) {
    System.out.println("File is created at " + file.getCanonicalPath());
} else {
    System.out.println("File already exists.");
}

It outputs:

Current working directory: /Users/Wasi/NetBeansProjects/TestProject
Changing working directory...
Current working directory: /Users/Wasi/NetBeansProjects/TestProject/test/
File is created at /Users/Wasi/NetBeansProjects/TestProject/test/test.txt
2 of 7
2

I am looking to find the working directory of a dynamically created process in Java,

You can certainly lookup the working directory of the current Java process by looking at the value of the user.dir system property:

String cwd = System.getProperty("user.dir");

But finding out the working directory of another process is not possible unless you are using special OS calls. On Linux, if you know the pid then you can look at /proc/[pid]/cwd but there is no easy equivalent in OSX or Windows that I know about.

This does not work, once it finishes it comes out with the same working directory.

Yeah, you are not able to issue a command to change the working directory because once the cmd exits, the working directory will be reset.

According to this page, you can set the working directory by assigning the user.dir system property:

System.setProperty("user.dir", "/tmp");

However this may be OS dependent and doesn't work on my OSX box. For example, the following code creates the x1 and x2 files in the same directory:

new File("x1").createNewFile();
// this doesn't seem to do anything
System.setProperty("user.dir", "/tmp");
new File("x2").createNewFile();

This answer says that there is no reliable way to do this in Java. I've always taken the opinion that you can't change the working directory and that you should be specific with new File(parent, filename) to show where files live, etc..

🌐
Java Code Geeks
javacodegeeks.com › home › core java
How to Traverse All Files from a Folder in Java - Java Code Geeks
June 7, 2024 - The File class is part of the java.io package and has been available since Java 1.0. It provides basic methods to list files and directories. To traverse all files and folders, including those within subdirectories, we need to recursively process each directory.
🌐
IncludeHelp
includehelp.com › java › processbuilder-directory-method-with-example.aspx
Java ProcessBuilder directory() method with example
If it returns null to indicate the current working directory of the current process so the name of the directory will be assigned by using system property "user.dir" assign. directory(File dir) method is used to return the working directory of this process builder.
🌐
Tutorialspoint
tutorialspoint.com › java › lang › processbuilder_directory.htm
Java ProcessBuilder directory() Method
The Java ProcessBuilder directory() method returns this process builder's working directory. Subprocesses subsequently started by this object's start() method will use this as their working directory. The returned value may be null ? this means to use the working directory of the current Java proces
Top answer
1 of 5
39

As Jarrod Roberson states in his answer here:

One way would be to use the system property System.getProperty("user.dir"); this will give you "The current working directory when the properties were initialized". This is probably what you want. to find out where the java command was issued, in your case in the directory with the files to process, even though the actual .jar file might reside somewhere else on the machine. Having the directory of the actual .jar file isn't that useful in most cases.

The following will print out the current directory from where the command was invoked regardless where the .class or .jar file the .class file is in.

public class Test
{
    public static void main(final String[] args)
    {
        final String dir = System.getProperty("user.dir");
        System.out.println("current dir = " + dir);
    }
}  

if you are in /User/me/ and your .jar file containing the above code is in /opt/some/nested/dir/ the command java -jar /opt/some/nested/dir/test.jar Test will output current dir = /User/me.

You should also as a bonus look at using a good object oriented command line argument parser. I highly recommend JSAP, the Java Simple Argument Parser. This would let you use System.getProperty("user.dir") and alternatively pass in something else to over-ride the behavior. A much more maintainable solution. This would make passing in the directory to process very easy to do, and be able to fall back on user.dir if nothing was passed in.

Example : GetExecutionPath

import java.util.*;
import java.lang.*;

public class GetExecutionPath
{
  public static void main(String args[]) {
    try{
      String executionPath = System.getProperty("user.dir");
      System.out.print("Executing at =>"+executionPath.replace("\\", "/"));
    }catch (Exception e){
      System.out.println("Exception caught ="+e.getMessage());
    }
  }
}

output for the above will be like

C:\javaexamples>javac GetExecutionPath.jav

C:\javaexamples>java GetExecutionPath
Executing at =>C:/javaexamples
2 of 5
9

You can do some crazy stuff:

String absolute = getClass().getProtectionDomain().getCodeSource().getLocation().toExternalForm();
absolute = absolute.substring(0, absolute.length() - 1);
absolute = absolute.substring(0, absolute.lastIndexOf("/") + 1);
String configPath = absolute + "config/file.properties";
String os = System.getProperty("os.name");
if (os.indexOf("Windows") != -1) {
    configPath = configPath.replace("/", "\\\\");
    if (configPath.indexOf("file:\\\\") != -1) {
        configPath = configPath.replace("file:\\\\", "");
    }
} else if (configPath.indexOf("file:") != -1) {
    configPath = configPath.replace("file:", "");
}

I use this to read out a config file relativ to execution path. You can use it also to get execution path of your jar file.

🌐
Medium
medium.com › @AlexanderObregon › javas-files-walk-method-explained-570d8a67247d
Java’s Files.walk() Method Explained | Medium
September 3, 2024 - This step-by-step traversal, filtering, and counting process gives you the total number of regular files in the directory tree starting from the specified directory. Another common use case is searching for files that match a specific pattern. For example, you might want to find all .java files ...
🌐
Baeldung
baeldung.com › home › java › java io › list files in a directory in java
List Files in a Directory in Java | Baeldung
January 8, 2024 - As we can see, listFiles() returns an array of File objects that are the contents of the directory. We’ll create a stream from that array. Then we’ll filter away all the values that aren’t subdirectories. Finally, we’ll collect the result into a set.
🌐
ZetCode
zetcode.com › java › listdirectory
Java list directory - how to show directory contents in Java
May 11, 2024 - This method is powerful for scenarios where you need to process or analyze every file within a directory and its subdirectories, such as searching for specific file types, aggregating data, or performing batch operations. The stream can be filtered to include only files, directories, or other criteria as needed. ... import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; void main() throws IOException { String pathName = ".."; try (Stream<Path> paths = Files.walk(Paths.get(pathName))) { paths.filter(Files::isRegularFile) .forEach(System.out::println); } }
🌐
Stack Overflow
stackoverflow.com › questions › 29953820 › java-retrieve-working-directory-of-current-process-builder
Java: Retrieve working directory of current process builder - Stack Overflow
April 29, 2015 - futures = new ArrayList<Future<String>>(); executor = Executors.newFixedThreadPool(10); for (int i=0; i<cnt;i++) { ProcessBuilder builder = new ProcessBuilder(); builder.command("java","app2"); //I set the class path in the real code builder.directory(new File("/Users/Evan/Documents/workspace/MyProj/ins_"+i)); builder.inheritIO(); ProcessRunner pr=new ProcessRunner (builder); futures.add(executor.submit(pr)); }
🌐
javathinking
javathinking.com › blog › how-can-i-read-all-files-in-a-folder-from-java
How to Read All Files in a Folder Using Java: Complete Guide with Examples — javathinking.com
Resource Safety: DirectoryStream is auto-closed via try-with-resources (critical to prevent leaks). Java 8 introduced Files.list(Path), which returns a Stream<Path> for processing files/directories.