在 Java 中更改当前工作目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/840190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing the current working directory in Java?
提问by Nick
How can I change the current working directory from within a Java program? Everything I've been able to find about the issue claims that you simply can't do it, but I can't believe that that's really the case.
如何从 Java 程序中更改当前工作目录?我所能找到的关于这个问题的一切都声称你根本做不到,但我不敢相信事实确实如此。
I have a piece of code that opens a file using a hard-coded relative file path from the directory it's normally started in, and I just want to be able to use that code from within a different Java program without having to start it from within a particular directory. It seems like you should just be able to call System.setProperty( "user.dir", "/path/to/dir" )
, but as far as I can figure out, calling that line just silently fails and does nothing.
我有一段代码,它使用硬编码的相对文件路径从它通常启动的目录中打开一个文件,我只想能够在不同的 Java 程序中使用该代码,而不必从内部启动它一个特定的目录。看起来您应该只能调用System.setProperty( "user.dir", "/path/to/dir" )
,但据我所知,调用该行只是默默地失败并且什么也不做。
I would understand if Java didn't allow you to do this, if it weren't for the fact that it allows you to getthe current working directory, and even allows you to open files using relative file paths....
我会理解 Java 是否不允许您这样做,如果不是因为它允许您获取当前工作目录,甚至允许您使用相对文件路径打开文件....
采纳答案by Michael Myers
There is no reliable way to do this in pure Java. Setting the user.dir
property via System.setProperty()
or java -Duser.dir=...
does seem to affect subsequent creations of Files
, but not e.g. FileOutputStreams
.
在纯 Java 中没有可靠的方法来做到这一点。user.dir
通过System.setProperty()
or设置属性java -Duser.dir=...
似乎会影响 的后续创建Files
,但不会影响例如FileOutputStreams
。
The File(String parent, String child)
constructor can help if you build up your directory path separately from your file path, allowing easier swapping.
的File(String parent, String child)
,如果你从你的文件路径单独建立你的目录路径,用户可以方便地交换构造可以提供帮助。
An alternative is to set up a script to run Java from a different directory, or use JNI native code as suggested below.
另一种方法是设置一个脚本来从不同的目录运行 Java,或者使用 JNI 本机代码,如下所示。
The relevant Sun bugwas closed in 2008 as "will not fix".
相关的 Sun 错误在 2008 年被关闭,因为“不会修复”。
回答by Adam Paynter
If I understand correctly, a Java program starts with a copyof the current environment variables. Any changes via System.setProperty(String, String)
are modifying the copy, not the original environment variables. Not that this provides a thorough reason as to why Sun chose this behavior, but perhaps it sheds a little light...
如果我理解正确,Java 程序以当前环境变量的副本开始。通过的任何更改System.setProperty(String, String)
都是修改副本,而不是原始环境变量。并不是说这为 Sun 选择这种行为的原因提供了一个彻底的理由,但也许它可以说明一点……
回答by rapha?λ
The working directory is a operating system feature (set when the process starts).
Why don't you just pass your own System property (-Dsomeprop=/my/path
) and use that in your code as the parent of your File:
工作目录是操作系统功能(在进程启动时设置)。为什么不直接传递自己的 System 属性 ( -Dsomeprop=/my/path
) 并在代码中将其用作 File 的父级:
File f = new File ( System.getProperty("someprop"), myFilename)
回答by matt b
The smarter/easier thing to do here is to just change your code so that instead of opening the file assuming that it exists in the current working directory (I assume you are doing something like new File("blah.txt")
, just build the path to the file yourself.
在这里做的更聪明/更容易的事情是只更改您的代码,而不是假设它存在于当前工作目录中打开文件(我假设您正在执行类似的操作new File("blah.txt")
,只需自己构建文件的路径。
Let the user pass in the base directory, read it from a config file, fall back to user.dir
if the other properties can't be found, etc. But it's a whole lot easier to improve the logic in your program than it is to change how environment variables work.
让用户传入基本目录,从配置文件中读取它,user.dir
如果找不到其他属性,则回退到其他属性,等等。但是改进程序中的逻辑比更改方式要容易得多环境变量工作。
回答by PhiLho
If you run your legacy program with ProcessBuilder, you will be able to specify its working directory.
如果您使用ProcessBuilder运行旧程序,您将能够指定其工作目录。
回答by Nathan Feger
The other possible answer to this question may depend on the reason you are opening the file. Is this a property file or a file that has some configuration related to your application?
此问题的其他可能答案可能取决于您打开文件的原因。这是属性文件还是具有与您的应用程序相关的某些配置的文件?
If this is the case you may consider trying to load the file through the classpath loader, this way you can load any file Java has access to.
如果是这种情况,您可以考虑尝试通过类路径加载器加载文件,这样您就可以加载 Java 有权访问的任何文件。
回答by Allen Rohner
It is possible to change the PWD, using JNA/JNI to make calls to libc. The JRuby guys have a handy java library for making POSIX calls called jna-posixHere's the maven info
可以更改 PWD,使用 JNA/JNI 调用 libc。JRuby 人员有一个方便的 Java 库,用于进行名为jna-posix 的POSIX 调用,这是 maven 信息
You can see an example of its use here(Clojure code, sorry). Look at the function chdirToRoot
您可以在此处查看其使用示例(Clojure 代码,抱歉)。看函数chdirToRoot
回答by lesolorzanov
If you run your commands in a shell you can write something like "java -cp" and add any directories you want separated by ":" if java doesnt find something in one directory it will go try and find them in the other directories, that is what I do.
如果你在 shell 中运行你的命令,你可以写一些类似“java -cp”的东西,并添加任何你想用“:”分隔的目录,如果 java 在一个目录中没有找到一些东西,它会尝试在其他目录中找到它们,那就是是我做的。
回答by Steve K
There isa way to do this using the system property "user.dir". The key part to understand is that getAbsoluteFile() must be called (as shown below) or else relative paths will be resolved against the default"user.dir" value.
这里是一个办法做到这一点使用系统属性“user.dir来”。要理解的关键部分是必须调用 getAbsoluteFile()(如下所示),否则将根据默认的“user.dir”值解析相对路径。
import java.io.*;
public class FileUtils
{
public static boolean setCurrentDirectory(String directory_name)
{
boolean result = false; // Boolean indicating whether directory was set
File directory; // Desired current working directory
directory = new File(directory_name).getAbsoluteFile();
if (directory.exists() || directory.mkdirs())
{
result = (System.setProperty("user.dir", directory.getAbsolutePath()) != null);
}
return result;
}
public static PrintWriter openOutputFile(String file_name)
{
PrintWriter output = null; // File to open for writing
try
{
output = new PrintWriter(new File(file_name).getAbsoluteFile());
}
catch (Exception exception) {}
return output;
}
public static void main(String[] args) throws Exception
{
FileUtils.openOutputFile("DefaultDirectoryFile.txt");
FileUtils.setCurrentDirectory("NewCurrentDirectory");
FileUtils.openOutputFile("CurrentDirectoryFile.txt");
}
}
回答by Bizmarck
As mentioned you can't change the CWD of the JVM but if you were to launch another process using Runtime.exec() you can use the overloaded method that lets you specify the working directory. This is not really for running your Java program in another directory but for many cases when one needs to launch another program like a Perl script for example, you can specify the working directory of that script while leaving the working dir of the JVM unchanged.
如前所述,您无法更改 JVM 的 CWD,但是如果您要使用 Runtime.exec() 启动另一个进程,您可以使用重载方法来指定工作目录。这并不是为了在另一个目录中运行您的 Java 程序,而是在许多情况下,当您需要启动另一个程序(例如 Perl 脚本)时,您可以指定该脚本的工作目录,同时保持 JVM 的工作目录不变。
See Runtime.execjavadocs
请参阅Runtime.execjavadocs
Specifically,
具体来说,
public Process exec(String[] cmdarray,String[] envp, File dir) throws IOException
where dir
is the working directory to run the subprocess in
dir
运行子进程的工作目录在哪里