[java] How to get the current working directory in Java?

I want to access my current working directory using java.

My code :

 String current = new java.io.File( "." ).getCanonicalPath();
        System.out.println("Current dir:"+current);
 String currentDir = System.getProperty("user.dir");
        System.out.println("Current dir using System:" +currentDir);

Output:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

My output is not correct because C drive is not my current directory.

How to get the current directory ?

This question is related to java java-io

The answer is


The following works on Java 7 and up (see here for documentation).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();

Current working directory is defined differently in different Java implementations. For certain version prior to Java 7 there was no consistent way to get the working directory. You could work around this by launching Java file with -D and defining a variable to hold the info

Something like

java -D com.mycompany.workingDir="%0"

That's not quite right, but you get the idea. Then System.getProperty("com.mycompany.workingDir")...


What makes you think that c:\windows\system32 is not your current directory? The user.dir property is explicitly to be "User's current working directory".

To put it another way, unless you start Java from the command line, c:\windows\system32 probably is your CWD. That is, if you are double-clicking to start your program, the CWD is unlikely to be the directory that you are double clicking from.

Edit: It appears that this is only true for old windows and/or Java versions.


this is current directory name

String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();

this is current directory path

String path=folder.getPath();

This is the solution for me

File currentDir = new File("");

None of the answers posted here worked for me. Here is what did work:

java.nio.file.Paths.get(
  getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);

Edit: The final version in my code:

URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
    myURI = myURL.toURI();
} catch (URISyntaxException e1) 
{}
return java.nio.file.Paths.get(myURI).toFile().toString()

generally, as a File object:

File getCwd() {
  return new File("").getAbsoluteFile();
}

you may want to have full qualified string like "D:/a/b/c" doing:

getCwd().getAbsolutePath()

This will give you the path of your current working directory:

Path path = FileSystems.getDefault().getPath(".");

And this will give you the path to a file called "Foo.txt" in the working directory:

Path path = FileSystems.getDefault().getPath("Foo.txt");

Edit : To obtain an absolute path of current directory:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

* Update * To get current working directory:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();

assume that you're trying to run your project inside eclipse, or netbean or stand alone from command line. I have write a method to fix it

public static final String getBasePathForClass(Class<?> clazz) {
    File file;
    try {
        String basePath = null;
        file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
            basePath = file.getParent();
        } else {
            basePath = file.getPath();
        }
        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbean
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    } catch (URISyntaxException e) {
        throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
    }
}

To use, everywhere you want to get base path to read file, you can pass your anchor class to above method, result may be the thing you need :D

Best,


Code :

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

This will print the absolute path of the current directory from where your application was initialized.


Explanation:

From the documentation:

java.io package resolve relative pathnames using current user directory. The current directory is represented as system property, that is, user.dir and is the directory from where the JVM was invoked.


Using Windows user.dir returns the directory as expected, but NOT when you start your application with elevated rights (run as admin), in that case you get C:\WINDOWS\system32


System.getProperty("java.class.path")


Use CodeSource#getLocation().

This works fine in JAR files as well. You can obtain CodeSource by ProtectionDomain#getCodeSource() and the ProtectionDomain in turn can be obtained by Class#getProtectionDomain().

public class Test {
    public static void main(String... args) throws Exception {
        URL location = Test.class.getProtectionDomain().getCodeSource().getLocation();
        System.out.println(location.getFile());
    }
}

This is my silver bullet when ever the moment of confusion bubbles in.(Call it as first thing in main). Maybe for example JVM is slipped to be different version by IDE. This static function searches current process PID and opens VisualVM on that pid. Confusion stops right there because you want it all and you get it...

  public static void callJVisualVM() {
    System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
    //next search current jdk/jre
    String jre_root = null;
    String start = "vir";
    try {
        java.lang.management.RuntimeMXBean runtime =
                java.lang.management.ManagementFactory.getRuntimeMXBean();
        String jvmName = runtime.getName();
        System.out.println("JVM Name = " + jvmName);
        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        Runtime thisRun = Runtime.getRuntime();
        jre_root = System.getProperty("java.home");
        System.out.println("jre_root:" + jre_root);
        start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
        thisRun.exec(start);
    } catch (Exception e) {
        System.getProperties().list(System.out);
        e.printStackTrace();
    }
}

I hope you want to access the current directory including the package i.e. If your Java program is in c:\myApp\com\foo\src\service\MyTest.java and you want to print until c:\myApp\com\foo\src\service then you can try the following code:

String myCurrentDir = System.getProperty("user.dir")
            + File.separator
            + System.getProperty("sun.java.command")
                    .substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
                    .replace(".", File.separator);
    System.out.println(myCurrentDir);

Note: This code is only tested in Windows with Oracle JRE.


I'm on Linux and get same result for both of these approaches:

@Test
public void aaa()
{
    System.err.println(Paths.get("").toAbsolutePath().toString());

    System.err.println(System.getProperty("user.dir"));
}

Paths.get("") docs

System.getProperty("user.dir") docs


Mention that it is checked only in Windows but i think it works perfect on other Operating Systems [Linux,MacOs,Solaris] :).


I had 2 .jar files in the same directory . I wanted from the one .jar file to start the other .jar file which is in the same directory.

The problem is that when you start it from the cmd the current directory is system32.


Warnings!

  • The below seems to work pretty well in all the test i have done even with folder name ;][[;'57f2g34g87-8+9-09!2#@!$%^^&() or ()%&$%^@# it works well.
  • I am using the ProcessBuilder with the below as following:

..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

getBasePathForClass(Class<?> classs):

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }

On Linux when you run a jar file from terminal, these both will return the same String: "/home/CurrentUser", no matter, where youre jar file is. It depends just on what current directory are you using with your terminal, when you start the jar file.

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

If your Class with main would be called MainClass, then try:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

This will return a String with absolute path of the jar file.


this.getClass().getClassLoader().getResource("").getPath()

See: http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

Using java.nio.file.Path and java.nio.file.Paths, you can do the following to show what Java thinks is your current path. This for 7 and on, and uses NIO.

Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);

This outputs Current relative path is: /Users/george/NetBeansProjects/Tutorials that in my case is where I ran the class from. Constructing paths in a relative way, by not using a leading separator to indicate you are constructing an absolute path, will use this relative path as the starting point.


This isn't exactly what's asked, but here's an important note: When running Java on a Windows machine, the Oracle installer puts a "java.exe" into C:\Windows\system32, and this is what acts as the launcher for the Java application (UNLESS there's a java.exe earlier in the PATH, and the Java app is run from the command-line). This is why File(".") keeps returning C:\Windows\system32, and why running examples from macOS or *nix implementations keep coming back with different results from Windows.

Unfortunately, there's really no universally correct answer to this one, as far as I have found in twenty years of Java coding unless you want to create your own native launcher executable using JNI Invocation, and get the current working directory from the native launcher code when it's launched. Everything else is going to have at least some nuance that could break under certain situations.


Java 11 and newer

This solution is better than others and more portable:

Path cwd = Paths.get("").toAbsolutePath();

Or even

String cwd = Paths.get("").toAbsolutePath().toString();

Try something like this I know I am late for the answer but this obvious thing happened in java8 a new version from where this question is asked but..

The code

import java.io.File;

public class Find_this_dir {

    public static void main(String[] args) {

//some sort of a bug in java path is correct but file dose not exist
        File this_dir = new File("");

//but these both commands work too to get current dir        
//      File this_dir_2 = new File(this_dir.getAbsolutePath());
        File this_dir_2 = new File(new File("").getAbsolutePath());

        System.out.println("new File(" + "\"\"" + ")");
        System.out.println(this_dir.getAbsolutePath());
        System.out.println(this_dir.exists());
        System.out.println("");
        System.out.println("new File(" + "new File(" + "\"\"" + ").getAbsolutePath()" + ")");
        System.out.println(this_dir_2.getAbsolutePath());
        System.out.println(this_dir_2.exists());
    }
}

This will work and show you the current path but I don't now why java fails to find current dir in new File(""); besides I am using Java8 compiler...

This works just fine I even tested it new File(new File("").getAbsolutePath());

Now you have current directory in a File object so (Example file object is f then),

f.getAbsolutePath() will give you the path in a String varaible type...

Tested in another directory that is not drive C works fine