我想使用 Java 访问我当前的工作目录。
我的代码:
String currentPath = new java.io.File(".").getCanonicalPath();
System.out.println("Current dir:" + currentPath);
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 驱动器不是我的当前目录。
如何获取当前目录?
代码 :
public class JavaApplication {
public static void main(String[] args) {
System.out.println("Working Directory = " + System.getProperty("user.dir"));
}
}
这将打印初始化应用程序的当前目录的绝对路径。
解释:
java.io
包使用当前用户目录解析相对路径名。当前目录表示为系统属性,即 user.dir
,是调用 JVM 的目录。
请参阅:Path Operations (The Java™ Tutorials > Essential Classes > Basic I/O)。
使用 java.nio.file.Path
和 java.nio.file.Paths
,您可以执行以下操作来显示 Java 认为您当前的路径。这适用于 7 及更高版本,并使用 NIO。
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current absolute path is: " + s);
这输出:
Current absolute path is: /Users/george/NetBeansProjects/Tutorials
就我而言,这就是我上课的地方。
以相对方式构建路径,通过不使用前导分隔符来指示您正在构建绝对路径,将使用此相对路径作为起点。
Paths.get("").getParent()
,它给出了 null
。相反,这有效:Paths.get("").toAbsolutePath().getParent()
。
以下适用于 Java 7 及更高版本(有关文档,请参阅 here)。
import java.nio.file.Paths;
Paths.get(".").toAbsolutePath().normalize().toString();
import java.io.File; File(".").getAbsolutePath()
更好吗?
Paths.get()
可能被认为更好,因为它可以直接访问更强大的 Path
界面。
.normalize()
的潜在优势是什么?
Returns a path that is this path with redundant name elements eliminated.
.
(点)的意义是什么?如果我们省略点有关系吗?
这将为您提供当前工作目录的路径:
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();
Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Path
对象,指向当前工作目录中名为 .
的文件。使用空字符串而不是 "."
对我有用。
Java 11 及更新版本
此解决方案比其他解决方案更好,更便携:
Path cwd = Path.of("").toAbsolutePath();
甚至
String cwd = Path.of("").toAbsolutePath().toString();
这是我的解决方案
File currentDir = new File("");
new File("").getAbsoluteFile()
。
.
的文件。
是什么让您认为 c:\windows\system32 不是您的当前目录? user.dir
属性明确为“用户的当前工作目录”。
换句话说,除非您从命令行启动 Java,否则 c:\windows\system32 可能是您的 CWD。也就是说,如果您双击启动程序,则 CWD 不太可能是您从中双击的目录。
编辑:看来这仅适用于旧 Windows 和/或 Java 版本。
user.dir
始终是我双击 jar 文件的文件夹。
这在 JAR 文件中也可以正常工作。您可以通过ProtectionDomain#getCodeSource()
获得CodeSource
,而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());
}
}
this.getClass().getClassLoader().getResource("").getPath()
""
。不是要求的。
getClass()
是一种对象方法,因此在静态上下文中仅删除 this
是行不通的。您必须通过执行 MyClass.class.getClassLoader().....
来明确引用您所在的类。
通常,作为 File 对象:
File getCwd() {
return new File("").getAbsoluteFile();
}
您可能希望拥有像 "D:/a/b/c" 这样的完整限定字符串:
getCwd().getAbsolutePath()
我在 Linux 上,这两种方法都得到了相同的结果:
@Test
public void aaa()
{
System.err.println(Paths.get("").toAbsolutePath().toString());
System.err.println(System.getProperty("user.dir"));
}
System.getProperty("user.dir")
docs
我希望您想访问包含包的当前目录,即如果您的 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);
注意:此代码仅在 Windows 中使用 Oracle JRE 进行测试。
File.separator
代替,或多参数 File
构造函数); 3. 命令行中指定了类路径,和 '当前目录包括包'(??) 是:首先指定,b。绝对指定,c。与 CWD 完全匹配(即使 Windows 不区分大小写),并且 d.是 CWD 的后代
在 Linux 上,当您从 终端 运行 jar 文件时,它们都将返回相同的 String
:"/ home/CurrentUser",不管你的 jar 文件在哪里。当您启动 jar 文件时,这仅取决于您在终端上使用的当前目录。
Paths.get("").toAbsolutePath().toString();
System.getProperty("user.dir");
如果您的 Class
和 main
将被称为 MainClass
,请尝试:
MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();
这将返回带有 jar 文件的绝对路径 的 String
。
使用 Windows user.dir 按预期返回目录,但不是当您以提升的权限(以管理员身份运行)启动应用程序时,在这种情况下您会得到 C:\WINDOWS\system32
提到它仅在 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;
}
假设您正在尝试在 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
最好的,
对于 Java 11,您还可以使用:
var path = Path.of(".").toRealPath();
当前工作目录在不同的 Java 实现中定义不同。对于 Java 7 之前的某些版本,没有一致的方法来获取工作目录。您可以通过使用 -D
启动 Java 文件并定义一个变量来保存信息来解决此问题
就像是
java -D com.mycompany.workingDir="%0"
这不太对,但你明白了。然后System.getProperty("com.mycompany.workingDir")
...
当混乱的时刻冒出来时,这是我的灵丹妙药。(将其称为主要的第一件事)。也许例如 JVM 被 IDE 滑入不同的版本。此静态函数搜索当前进程 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();
}
}
这并不是所要求的,但这里有一个重要说明:在 Windows 机器上运行 Java 时,Oracle 安装程序会将“java.exe”放入 C:\Windows\system32,这就是作为Java 应用程序(除非 PATH 中有一个 java.exe,并且 Java 应用程序是从命令行运行的)。这就是为什么 File(".") 不断返回 C:\Windows\system32,以及为什么从 macOS 或 *nix 实现中运行的示例不断返回来自 Windows 的不同结果的原因。
不幸的是,据我在 20 年的 Java 编码中发现,这确实没有普遍正确的答案,除非您想使用 JNI 调用创建自己的本机启动器可执行文件,并在何时从本机启动器代码中获取当前工作目录它启动了。其他一切都将至少有一些细微差别,在某些情况下可能会破裂。
\programdata\Oracle\Java\javapath
或 \Program Files [(x86)]\Common Files\Oracle\Java\javapath
中,如 MS 批准
尝试这样的事情我知道我迟到了答案,但是这个明显的事情发生在 java8 一个新版本中,从那里提出这个问题但是..
编码
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());
}
}
这将起作用并向您显示当前路径,但我现在不知道为什么 java 无法在 new File("");
中找到当前目录,除了我使用的是 Java8 编译器...
这很好用,我什至测试过它new File(new File("").getAbsolutePath());
现在您在 File 对象中有当前目录(示例文件对象是 f 然后),
f.getAbsolutePath()
将为您提供字符串变量类型的路径...
在不是驱动器 C 的另一个目录中测试工作正常
我最喜欢的方法是从附加到当前运行进程的系统环境变量中获取它。在这种情况下,您的应用程序由 JVM 管理。
String currentDir = System.getenv("PWD");
/*
/home/$User/Documents/java
*/
要查看您可能会发现有用的其他环境变量,例如主目录、操作系统版本......
//Home directory
String HomeDir = System.getEnv("HOME");
//Outputs for unix
/home/$USER
//Device user
String user = System.getEnv("USERNAME");
//Outputs for unix
$USER
这种方法的美妙之处在于,所有类型的操作系统平台的所有路径都将得到解决
c//user//
您可以使用 new File("./")
。这样 isDirectory()
返回 true(至少在 Windows 平台上)。另一方面,new File("") isDirectory()
返回 false。
这是一个非常混乱的话题,在提供真正的解决方案之前,我们需要了解一些概念。
File 和 NIO File Api 方法使用相对路径“”或“.”。在内部使用系统参数“user.dir”值来确定返回位置。 “user.dir”值基于 USER 工作目录,该值的行为取决于操作系统和 jar 的执行方式。例如,使用文件资源管理器(通过双击打开它)从 Linux 执行 JAR 将使用用户主目录设置 user.dir,而不管 jar 的位置。如果从命令行执行相同的 jar,它将返回 jar 位置,因为每个 cd 命令到 jar 位置都修改了工作目录。
话虽如此,使用 Java NIO
、Files
或 "user.dir"
属性的解决方案将适用于 "user.dir"
具有正确值的所有方案。
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
我们可以使用以下代码:
new File(MyApp.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI().getPath())
.getParent();
获取已执行 JAR 的当前位置,我个人使用以下方法获取预期位置并在应用程序一开始覆盖 "user.dir"
系统属性。因此,稍后当使用其他方法时,我将始终获得预期值。
更多细节在这里-> https://blog.adamgamboa.dev/getting-current-directory-path-in-java/
public class MyApp {
static {
//This static block runs at the very begin of the APP, even before the main method.
try{
File file = new File(MyApp.class.getProtectionDomain().getCodeSource()
.getLocation().toURI().getPath());
String basePath = file.getParent();
//Overrides the existing value of "user.dir"
System.getProperties().put("user.dir", basePath);
}catch(URISyntaxException ex){
//log the error
}
}
public static void main(String args []){
//Your app logic
//All these approaches should return the expected value
//regardless of the way the jar is executed.
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
}
}
我希望这个解释和细节对其他人有帮助......
这里发布的答案都不适合我。这是起作用的:
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()
System.getProperty("java.class.path")
不定期副业成功案例分享