Java:获取项目的绝对路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15606503/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:14:18  来源:igfitidea点击:

Java: get absolute path of project

javafile-io

提问by roverred

I'm trying to run a exe file in path outside of the current package. My code.java file that runs it is in

我正在尝试在当前包之外的路径中运行一个 exe 文件。我运行它的 code.java 文件在

%Workspace_path%\Project\src\main\java\com\util\code.java

However the directory of where the exe is

但是exe所在的目录

%Workspace_path%\Project\src\main\resources\program.exe

If possible, it seems like the best solution here would be to get the absolute path of the Project then append "src\main\resources\" to it. Is there a good way to do this or is there an alternative solution? I'm using Eclipse, but it would great if it could be used in other IDEs too. Thanks for any help.

如果可能的话,这里的最佳解决方案似乎是获取项目的绝对路径,然后将“src\main\resources\”附加到它。有没有好的方法可以做到这一点,或者有没有替代的解决方案?我正在使用 Eclipse,但如果它也可以用于其他 IDE,那就太好了。谢谢你的帮助。

回答by Mihai Danila

The de facto approach to solving this is to bundle the EXE as a classpath resource. It seems you have arranged for this already.

解决此问题的实际方法是将 EXE 作为类路径资源捆绑在一起。看来你已经安排好了。

When working with classpath resources, a mature program should not assume that the resource is in the filesystem. The resources could be packaged in a JAR file, or even in a WAR file. The only thing you can trust at that point is the standard methods for accessing resources in Java, as hinted below.

使用类路径资源时,成熟的程序不应假设资源位于文件系统中。资源可以打包在 JAR 文件中,甚至可以打包在 WAR 文件中。此时您唯一可以信任的是 Java 中访问资源的标准方法,如下所示。

The way to solve your problem, then, is to access the resource contents using the de facto standard of invoking Class.getResourceAsStream(or ClassLoader.getResourceAsStream), save the contents to a temporary file, and execute from that file. This will guarantee your program works correctly regardless of its packaging.

然后,解决您的问题的方法是使用事实上的调用标准Class.getResourceAsStream(或ClassLoader.getResourceAsStream)访问资源内容,将内容保存到临时文件,然后从该文件执行。这将保证您的程序正常运行,无论其包装如何。

In other words:

换句话说:

  1. Invoke getClass().getResourceAsStream("/program.exe"). From static methods, you can't call getClass, so use the name of your current class instead, as in MyClass.class.getResourceAsStream. This returns an InputStream.
  2. Create a temporary file, preferably using File.createTempFile. This returns a Fileobject identifying the newly created file.
  3. Open an OutputStreamto this temp file.
  4. Use the two streams to copy the data from the resource into the temp file. You can use IOUtils.copyif you're into Apache Commons tools. Don't forget to close the two streams when done with this step.
  5. Execute the program thus stored in the temporary file.
  6. Clean up.
  1. 调用getClass().getResourceAsStream("/program.exe"). 从静态方法中,您不能调用getClass,因此请改用当前类的名称,如MyClass.class.getResourceAsStream. 这将返回一个InputStream.
  2. 创建一个临时文件,最好使用File.createTempFile. 这将返回一个File标识新创建文件的对象。
  3. 打开OutputStream此临时文件。
  4. 使用这两个流将数据从资源复制到临时文件中。IOUtils.copy如果您喜欢 Apache Commons 工具,则可以使用。完成此步骤后,不要忘记关闭两个流。
  5. 执行这样存储在临时文件中的程序。
  6. 清理。

In other words (code snippet added later):

换句话说(稍后添加代码片段):

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.
        }
    }
}

回答by Harry.Chen

Well,in your context,the project root is happen to be the current path

好吧,在您的上下文中,项目根恰好是当前路径

.

.

,that is where the java.exe start to execute,so a easy way is:

,那是 java.exe 开始执行的地方,所以一个简单的方法是:

String exePath="src\main\resources\program.exe";
File exeFile=new File(".",exePath);
System.out.println(exeFile.getAbusolutePath());
...

I tested this code on Eclipse,It's ok. I think is should work on different ide. Good Luck!

我在 Eclipse 上测试了这段代码,没问题。我认为应该在不同的ide上工作。祝你好运!