有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

替换空格和其他字符的当前执行的java文件路径

在我的节目中我做到了

File jarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
execPath = String.valueOf(jarFile.getParentFile());

获取execPath=到当前执行的路径(最终.exe程序所在的位置)。Wich是我的主类的一个属性,我用它来处理和读取一些文件

但是,

在某些带有空格或重音符号的文件夹中运行程序时,execPath的值将替换为%number,如下所示

C:\Users\Hugo\OneDrive%20-%20Funda%c3%a7%c3%a3o%20para%20Inova%c3%a7%c3%b5es%20Tecnol%c3%b3gicas%20-%20FITec\Redes\AutoComRouter\

在哪里

OneDrive%20-%20Funda%c3%a7%c3%a3o%20para%20Inova%c3%a7%c3%b5es%20Tecnol%c3%b3gicas%20-%20FITec

应该是

OneDrive - Fundação para Inovações Tecnológicas - FITec

我想知道是否有可能去掉这个恼人的myexecpath属性替换项


共 (1) 个答案

  1. # 1 楼答案

    不要调用URL。getPath()方法。正如您现在看到的,它不会返回有效的文件名。它只返回URL的路径部分,即方案和主机之后的部分,所有百分比都会原封不动地转义

    将URL转换为文件的正确方法是converting it to a URI,然后constructing a File from that URI

    因此,正确的代码如下所示:

    CodeSource source = Main.class.getProtectionDomain().getCodeSource();
    if (source != null) {
        try {
            File jarFile = new File(source.getLocation().toURI());
            execPath = String.valueOf(jarFile.getParentFile());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
    

    注意检查nullThe code source can be null,这取决于类加载器愿意并且能够将多少信息传递给它创建的ProtectionDomain。这意味着试图找到一个目标的位置。运行时的jar文件不可靠

    如果要将本机可执行文件与。jar文件,这里有一些更可靠的选项:

    • 将脚本(Windows的批处理文件、其他系统的shell脚本)包含在您的应用程序中。jar文件,它将系统属性传递给程序,该程序包含可执行文件的位置
    • 将可执行文件打包到。jar文件,并在运行时将其复制到临时文件中,使其可执行

    第一种方法将使用系统来确定目录,因为可靠的,并将其传递给程序。例如,在Windows中:

    set execdir=%~dp0..\..
    javaw.exe "-Dexecutable.dir=%here%" -jar MyApplication.jar
    

    在Linux中:

    execdir=`dirname $0`/..
    java "-Dexecutable.dir=$execdir" -jar MyApplication.jar
    

    第二种方法需要创建您的应用程序。jar文件,其中包含可执行文件,然后在外部复制它们。当您想要运行它们时,可以使用jar:

    Path execDir = Files.createTempDirectory(null);
    execPath = execDir.toString();
    
    String[] executables;
    String os = System.getProperty("os.name");
    if (os.contains("Windows")) {
        executables = new String[] {
            "windows/foo.exe", "windows/bar.exe", "windows/baz.exe"
        };
    } else if (os.contains("Mac")) {
        executables = new String[] {
            "mac/foo", "mac/bar", "mac/baz"
        };
    } else {
        executables = new String[] {
            "linux/foo", "linux/bar", "linux/baz"
        };
    }
    
    for (String executable : executables) {
        String baseName = executable.substring(executable.lastIndexOf('/') + 1);
        Path newFile = execDir.resolve(baseName);
    
        try (InputStream executable =
            Main.class.getResourceAsStream(executable)) {
    
            Files.copy(executable, newFile);
        }
        if (Files.getFileStore(newFile).supportsFileAttributeView(
            PosixFileAttributeView.class)) {
    
            Set<PosixFilePermission> perms =
                Files.getPosixFilePermissions(newFile);
            perms.add(PosixFilePermission.OWNER_EXECUTE);
            Files.setPosixFilePermissions(newFile, perms);
        }
    }