我正在尝试在当前包之外的路径中运行一个 exe 文件。运行它的我的 code.java 文件在
%Workspace_path%\Project\src\main\java\com\util\code.java
但是exe所在的目录
%Workspace_path%\Project\src\main\resources\program.exe
如果可能的话,这里最好的解决方案似乎是获取项目的绝对路径,然后将“src\main\resources\”附加到它。有没有好的方法可以做到这一点或者是否有替代解决方案? 我正在使用 Eclipse,但如果它也可以用于其他 IDE,那就太好了。感谢您的帮助。
最佳答案
解决这个问题的实际方法是将 EXE 捆绑为类路径资源。看来你已经安排好了。
当使用类路径资源时,成熟的程序不应该假设资源在文件系统中。资源可以打包在 JAR 文件中,甚至可以打包在 WAR 文件中。在这一点上,您唯一可以信任的是在 Java 中访问资源的标准方法,如下所示。
那么,解决您的问题的方法是使用调用 Class.getResourceAsStream
的实际标准来访问资源内容。 (或 ClassLoader.getResourceAsStream
),将内容保存到临时文件,并从该文件执行。这将保证您的程序无论其包装如何都能正常工作。
换句话说:
- 调用
getClass().getResourceAsStream("/program.exe")
。您不能从静态方法调用getClass
,因此请改用当前类的名称,如MyClass.class.getResourceAsStream
。这将返回一个InputStream
。 - 创建一个临时文件,最好使用
File.createTempFile
.这将返回一个标识新创建文件的File
对象。 - 打开此临时文件的
OutputStream
。 - 使用这两个流将数据从资源复制到临时文件中。您可以使用
IOUtils.copy
如果您喜欢 Apache Commons 工具。完成此步骤后不要忘记关闭两个流。 - 执行存储在临时文件中的程序。
- 打扫卫生。
换句话说(后面添加的代码片段):
private void executeProgramFromClasspath() throws IOException {
// Open resource stream.
InputStream input = getClass().getResourceAsStream("/program.exe");
if (input == null) {
throw new IllegalStateException("Missing classpath resource.");
}
// Transfer.
OutputStream output = null;
try {
// Create temporary file. May throw IOException.
File temporaryFile = File.createTempFile(getClass().getName(), "");
output = new FileOutputStream(temporaryFile);
output = new BufferedOutputStream(output);
IOUtils.copy(input, output);
} finally {
// Close streams.
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(output);
}
// Execute.
try {
String path = temporaryFile.getAbsolutePath();
ProcessBuilder processBuilder = new ProcessBuilder(path);
Process process = processBuilder.start();
process.waitFor();
} catch (InterruptedException e) {
// Optional catch. Keeps the method signature uncluttered.
throw new IOException(e);
} finally {
// Clean up
if (!temporaryFile.delete()) {
// Log this issue, or throw an error.
}
}
}
关于Java:获取项目的绝对路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15606503/