如何获取Java中的当前工作目录?


1024

我想使用Java访问我当前的工作目录。

我的代码:

 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);

输出:

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

我的输出不正确,因为C驱动器不是我的当前目录。

如何获取当前目录?


2
您可以在此处将执行cd命令时执行命令时看到的内容粘贴到此处吗?
Nishant

3
您要通过访问工作目录来完成什么工作?可以通过使用类路径来代替吗?例如,如果您需要在文件系统上读取文本文件,则可以在类路径上轻松找到它。
Earldouglas 2011年

1
怎么样?您能详细说明一下吗?
C图形

1
有关在类路径上访问文件的某些信息,请参见stackoverflow.com/questions/1464291/…–
downeyt

7
出于调试目的,工作目录可能有助于了解程序是否似乎无法访问存在的文件。
nsandersen

Answers:


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

这将从您的应用程序初始化位置打印出完整的绝对路径。


文档中

java.io软件包使用当前用户目录解析相对路径名。当前目录表示为系统属性,也就是user.dir从其中调用JVM的目录。


25
@ubuntudroid:这就是为什么我特别提到它将打印应用程序初始化位置的路径的原因。我猜想线程启动器在启动commnad提示符(基本上在C:\ WINDOWS \ system32)后直接运行jar /程序。希望你明白我的意思。假设您投了反对票,请至少感谢您愿意留下回应。:)
Anuj Patel 2012年

1
user.dir将获取启动进程的文件夹的路径。要获取应用程序主文件夹的实际路径,请参阅下面的答案。
彼得·德

1
我的意思是“所有依赖它来查找当前目录的代码都会失败。” 并非所有代码都一般。(我要慢慢编辑原始评论)
SubOptimal 2014年

13
@SubOptimal(如果用户设置了-Duser.dir),可能他想在自定义工作目录中运行它。
barwnikk

5
@indyaah实际上这个答案是错误的,系统进程(cwd)的用户工作目录和当前工作目录之间存在细微的差别;大多数情况下,“ user.dir”指向一个(java)进程的cwd;但是“ user.dir”具有不同的语义,不得用于获取java进程的cwd;btw:还有更多属性可用于java流程docs.oracle.com/javase/tutorial/essential/environment/…仅供参考
comeGetSome 2015年

380

请参阅:http : //docs.oracle.com/javase/tutorial/essential/io/pathOps.html

使用java.nio.file.Pathjava.nio.file.Paths,您可以执行以下操作以显示Java认为当前的路径。这适用于7及以后,并使用NIO。

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

Current relative path is: /Users/george/NetBeansProjects/Tutorials在我的情况下,这输出的是我从中运行课程的地方。通过不使用前导分隔符来指示您正在构造绝对路径,以相对方式构造路径,将以该相对路径为起点。


2
第一个尚未选中,但是第二个实际上将获得您的主文件夹。不是运行应用程序的当前工作目录。
彼得·德

12
请不要混淆用户的主目录(在您的情况下为“ user.home”,/ Users / george)和当前工作目录(“ user.dir”),这将是您启动应用程序JVM的目录,因此可能类似于/ Users / george / workspace / FooBarProject)。
David

1
我更喜欢这种方式。当我需要工作目录的父,但这不是工作:Paths.get("").getParent(),它给null。相反,这个作品:Paths.get("").toAbsolutePath().getParent()
Ole VV

235

以下内容适用于Java 7及更高版本(请参见此处以获取文档)。

import java.nio.file.Paths;

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

11
这比便携性更好import java.io.File; File(".").getAbsolutePath()吗?
Evgeni Sergeev'6

8
当您说可移植性时,您是说它可在Java 6及更低版本中使用?Paths.get()可以认为它更好,因为它可以直接访问功能更强大的Path界面。
Ole VV

8
.normalize()在这种情况下使用的潜在优势是什么?
Ole VV

7
@ OleV.V。来自Javadoc :(规范化方法Returns a path that is this path with redundant name elements eliminated.
斯蒂芬

在这种情况下将已经标准化。
JM Becker

72

这将为您提供当前工作目录的路径:

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

这将为您提供工作目录中名为“ Foo.txt”的文件的路径:

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

编辑: 要获取当前目录的绝对路径:

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

*更新* 要获取当前工作目录:

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

11
这只是返回“。” 为了我。
约翰·克特吉克

3
是的,在许多系统中将引用工作目录。要获取绝对路径,您可以再添加一个方法调用Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();
马克

2
您不需要foo.txt,只需输入一个空字符串即可获取目录
john ktejik

1
在Windows(10)上,这只是给我一个Path指向.当前工作目录内名为的文件的对象。使用空字符串,而不是"."为我工作。
克鲁夫

36

这是我的解决方案

File currentDir = new File("");

1
当您使用这样的File对象作为另一个文件的父对象时,这会产生副作用:new File(new File(“”),“ subdir”)不能按预期工作
MRalwasser 2014年

13
要解决此问题,请new File("").getAbsoluteFile()改用。
MRalwasser 2014年

4
对于它的价值,我最好使用File(“。”)。
keshlam 2014年

如何在Java中定义相对路径 此页面对我有所帮助。我还假设我应该/在创建相对路径时使用。我错了,不要以开头/../也可以在目录树中向上移动。
Irrationalkilla

@keshlam这给了我当前目录中的一个文件.
KROW

32

我在评论中找到了这个解决方案,它比其他方法更好,并且更便于移植:

String cwd = new File("").getAbsolutePath();

甚至

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

这与comeGetSome的答案完全相同,实际上是Java <7方式
GoGoris

30

是什么让您认为c:\ windows \ system32不是您的当前目录?的user.dir属性明确地是“用户的当前工作目录”。

换句话说,除非您从命令行启动Java,否则c:\ windows \ system32可能是您的CWD。也就是说,如果双击启动程序,则CWD不太可能是您双击的目录。

编辑:看来这仅适用于旧的Windows和/或Java版本。


2
似乎并非如此,至少在使用Java 7的Windows 7计算机上不是这样,user.dir始终是我双击jar文件的文件夹。
2015年

26

采用 CodeSource#getLocation()

这在JAR文件中也可以正常工作。您可以CodeSource通过获得,ProtectionDomain#getCodeSource()ProtectionDomain反过来可以通过获得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());
    }
}

2
这将返回JAR文件的位置。不是要求什么。
user207421

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

12
当我通过双击从JAR文件启动应用程序时,抛出NPE。
马修·怀斯

2
""如果应用程序是从JAR文件或CLASSPATH元素运行的,则返回此值。不是要求什么。
user207421

@ Zizouz212 getClass()是一个对象方法,因此在静态上下文中,仅删除this不起作用。您必须通过这样做显式地引用您所在的类MyClass.class.getClassLoader().....
克鲁夫(Kröw)

然而,它不会返回工作目录...
Angel O'Sphere

18

通常,作为File对象:

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

您可能希望具有完整的合格字符串,例如“ D:/ a / b / c”,它是:

getCwd().getAbsolutePath()

1
由于Android不包含java.nio.file.Files,因此在Android测试中效果很好。
iamreptar 2015年

在静态上下文中似乎对我不起作用(新File(“”)引发NullPointerException)..?
nsandersen,2016年

2
@nsandersen,您可能使用了错误的File对象:System.out.println(new java.io.File(“”)。getAbsolutePath());
comeGetSome


5

Linux的,当你运行一个罐子从文件终端,这些都将返回相同的String“/家/ CurrentUser”,不管其中的youre jar文件。启动jar文件时,这取决于终端使用的当前目录。

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

System.getProperty("user.dir");

如果您的Classwith main将被调用MainClass,请尝试:

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

这将返回一个String带有绝对路径的的JAR文件。


3
这不是要求的。
user207421

5

使用Windows user.dir返回预期的目录,但是以提升的权限启动应用程序(以管理员身份运行)时不会返回该目录,在这种情况下,您将获得C:\ WINDOWS \ system32


3

我希望您要访问当前目录,包括该软件包,即,如果您的Java程序已插入c:\myApp\com\foo\src\service\MyTest.java并且要打印到此,c:\myApp\com\foo\src\service则可以尝试以下代码:

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);

注意:此代码仅在带有Oracle JRE的Windows中经过测试。


6
不拒绝这个答案将是不利的。发布前,请仔细考虑。您的代码将被破坏,除非所有这些都是正确的:1. JRE是Oracle的,否则将没有“ sun.java.command”系统属性→NPE;2.操作系统是Windows(改用Windows File.separator,或使用多参数File构造函数);3. classpath在命令行中指定,并且 “当前目录(包括包)”(??)为:首先指定; b。绝对指定c。完全匹配CWD(即使Windows不区分大小写),也d。是CWD的后代
Michael Scheper

该地址指向第1点和第2点。但是,除非我丢失了某些内容,否则您仍将依赖于在命令行(即,不在环境变量中)和“当前目录(包括程序包)”中指定的类路径。承认我不是很明白你的意思)是作为类路径中第一个元素的后代。并且大小写匹配问题仍然存在。抱歉,我的评论没有帮助。为了保持注释字符的限制,我牺牲了清晰度。
Michael Scheper 2013年

@Inversus,它只能在某些环境中“完美”运行;您刚好有幸在其中进行了测试。即使在测试环境集不足以包含它们的情况下,编写在合法的运行时环境中失败的软件也不是一种好习惯。
Charles Duffy 2014年

@CharlesDuffy是的,这不是一个好习惯。幸运的是,此解决方案“解决了我的特定问题”并未导致它“在合法的运行时环境中失败”。实际上,它除了解决我遇到的非常具体的问题(与该问题/答案只有些相关)外,还帮助我解决了此类故障并编写了更强大的代码。我想我很幸运能找到它。
Inversus

3

提及它仅在签入,Windows但我认为它在其他操作系统[ Linux,MacOs,Solaris] :) 上可以完美地工作。


我在同一目录中有2个 .jar文件。我希望从一个.jar文件开始.jar在同一目录中的另一个文件。

问题是,当您从cmd当前目录启动它时,该目录是system32


警告!

  • 以下似乎工作很好在所有的测试中,我已经甚至文件夹名称完成;][[;'57f2g34g87-8+9-09!2#@!$%^^&()()%&$%^@# 它工作得很好。
  • ProcessBuilder在以下使用以下内容:

🍂..

//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;
    }

这将返回JAR文件的位置。不是要求什么。
user207421

@EJP .jar文件的位置不是Java程序的当前工作目录吗?
GOXR3PLUS

2

在不同的Java实现中,当前工作目录的定义有所不同。对于Java 7之前的某些版本,没有一致的方法来获取工作目录。您可以通过使用启动Java文件-D并定义一个变量来保存信息来解决此问题。

就像是

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

那不是很正确,但是您知道了。那System.getProperty("com.mycompany.workingDir")...


6
与这个问题无关。
彼得·德

1
它确实对Java有意义-它是您使用相对路径名打开的文件相对于磁盘上的位置。
Rob I

2
是的,它有一个含义。我的话语选择不当。但是,您没有抓住要点-在Java 7之前,无法知道当前的工作目录,并且不同的实现对它们进行了设置……不同……
MJB 2014年

1

假设您正在尝试在eclipse,netbean或命令行中单独运行项目。我已经写了一种解决方法

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());
    }
}

使用时,在任何要获取文件基本路径的地方,都可以将锚类传递给上述方法,结果可能是您需要的东西:D

最好,


2
这将返回JAR文件的位置。不是要求什么。
user207421

@ user207421是的,我知道这个答案不是问题的真实答案,但是大多数时候,每个人都想获得“罐子所在的目录”而不是“命令行工作目录”。
巴登

0

这里发布的答案都没有对我有用。这是起作用的内容:

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

编辑:我的代码中的最终版本:

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()

这将返回JAR文件的位置。不是要求什么。
user207421

0

每当混乱的时刻冒出来的时候,这就是我的银子弹。例如,IDE可能会将JVM转换为其他版本。该静态函数搜索当前进程PID,并在该pid上打开VisualVM。混乱就在那里停止了,因为您想要全部并获得了...

  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();
    }
}


-7

这是当前目录名称

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

这是当前目录路径

String path=folder.getPath();

1
OP希望从中运行应用程序的当前工作目录。
Leif Gruenwoldt 2014年

这是您的主目录,不是当前的工作目录,可能是您的主目录。不是要求什么。
user207421
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.