实现改变Java工作目录的效果 [英] Achieving the effect of changing the Java working directory
问题描述
上下文:我的软件依赖于调用一个库,由于旧的限制,该库只能接受相对路径作为输入.我需要相对于已知目录的路径.图书馆可能会像
Context: My software depends on calling a library which can only accept relative paths as an input because of an old limitation. I need the paths to be relative to a known directory. The library might make a call internally like
java.io.File fooBar = new java.io.File("foo/bar");
我需要这个给我 /nwd/foo/bar
而不是 /cwd/foo/bar
where /cwd
是运行 java
的工作目录.
I need this to give me /nwd/foo/bar
and not, say, /cwd/foo/bar
where /cwd
is the working directory from which java
was run.
出于所有意图和目的,我无法修改此库的内部行为.手动覆盖实例化这些对象的方法基本上涉及重写整个库.
For all intents and purposes, I cannot modify the internal behavior of this library. Manually overriding the methods which instantiate these objects would involve basically rewriting the entire library.
一个诱人的解决方案是在调用库之前 System.setProperty("user.dir", "/nwd")
,但这实际上并没有给我想要的效果.事实上,如果我调用 fooBar.getAbsolutePath()
,我会得到想要的 /nwd/foo/bar
,但是如果我检查了 fooBar.exists()
或尝试打开文件进行读取或写入,看起来该文件不存在,因为它实际上是在尝试打开 /cwd/foo/bar
.事实上,如果 fooBar
被
A tempting solution would be to just System.setProperty("user.dir", "/nwd")
before calling the library, but this doesn't actually give me the desired effect. Indeed, if I called fooBar.getAbsolutePath()
, I would get the desired /nwd/foo/bar
, but if I checked fooBar.exists()
or tried to open the file for reading or writing, it would appear that the file doesn't exist, because it's actually trying to open /cwd/foo/bar
. In fact, if fooBar
were instead initialized by
java.io.File fooBar = new java.io.File(new java.io.File("foo/bar").getAbsolutePath());
那实际上是可行的,因为 File
对象实际上包含绝对引用.
that would actually work, because then the File
object actually contains absolute references.
此时,我感到非常沮丧,以至于我不在乎这是否需要一个 hacky 解决方案.我只需要改变工作目录的效果.
At this point, I'm so frustrated that I don't care if this requires a hacky solution. I just need the effect of changing the working directory.
推荐答案
改变库 CWD 的另一种方法是在不同的 Java 进程中启动它,您可以在启动时指定 CWD(请参阅例如 ProcessBuilder 文档).如果我理解正确的话,你目前的流程有点类似于
A very alternative way to change the CWD of the library would be to launch it in a different Java process, for which you can specify CWD at launch time (see for example ProcessBuilder documentation). If I understand the problem correctly, your current flow is somewhat similar to
launch program with CWD 'a'
use library X that expects CWD to be 'b' // <-- problem here
新的流程是
launch program with CWD 'a'
determine desired CWD for launching library X
launch wrapper for library X with CWD 'b'
internally, library X is happy because its CWD is as expected
当然,这将迫使您编写一个完整的包装器,并使用套接字和序列化或您选择的任何其他通信策略进行通信.从好的方面来说,这将允许您并行启动库的多个实例,而它们的 CWD 不会相互干扰 - 以 JVM 和通信开销为代价.
Of course, this will force you to write a full wrapper, and communicate it using sockets&serialization, or any other communication strategy of your choice. On the plus side, this will allow you to launch several instances of your library side-by-side, without their CWDs interfering with each other -- at the cost of JVM and communication overheads.
这篇关于实现改变Java工作目录的效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!