URL 编码、空格和特殊字符(例如:“+”)。如何正确管理文件路径?

URL encoding, white spaces and special characters (e.g.: "+"). How to properly manage file paths?

我一直在阅读大量关于 Java 路径编码和管理文件路径的正确方法(如 this one)的 Stack Overflow 帖子。不过,我真的不知道如何管理我的文件路径。

我想要实现的目标非常简单:以正确的方式编码我的 *.jar 文件路径,以便我可以将它用作 FileInputStream() 的输入:这样我可以加载一个properties 文件位于上述 *.jar 的同一文件夹中。

我已阅读 Java 文档,我了解到 URLDecoder 只是用空格转义特殊符号(如“+”),所以我无法真正了解我必须使用哪些方法组合获取文件的绝对路径,即使它包含的文件夹(不是我的错)名称是由空格和所述符号组成的。这是我的方法:

private FileInputStream loadInputPropertiesFile() {
    FileInputStream input = null;

    // Let's load the properties file from the *.jar file parent folder.
    File jarPath = new File(PropertiesManagement.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    String propertiesPath = String.format("%s/", jarPath.getParentFile().getAbsolutePath());

    propertiesPath = URLDecoder.decode(propertiesPath, StandardCharsets.UTF_8);

    // This part has been added just for tests, to better understand how file paths were encoded.
    try {
        URL url = jarPath.toURI().toURL();
        File path = Paths.get(url.toURI()).toFile();
        System.out.println(path);
    } catch (MalformedURLException | URISyntaxException e) {
        e.printStackTrace();
    }

    try {
        input = new FileInputStream(propertiesPath + CONFIG_FILE_PATH);
    } catch (FileNotFoundException e) {
        System.out.println("Properties file not found! Have you deleted it?");
        e.printStackTrace();
    }

    return input;
}

编辑
我想要获取的文件路径是这样的:“C:\Some + Folder\x64”.
最后,返回的输入应该是这样的:“C:\Some + Folder\x64\config.properties”.

您只需将父文件夹添加到类路径,然后照常加载它:

//load a properties file from class path, inside static method
Properties prop = new Properties();
try(final InputStream stream = 
   Classname.class.getClassLoader().getResourceAsStream("foo.properties")) {
    prop.load(stream);
}
// or load it within an instance
try(final InputStream stream =
    this.getClass().getResourceAsStream("foo.properties")) {
    prop.load(stream);
}

而不是“%s/”,最好使用“%s”+ File.separator,这将始终为您提供独立于平台的分隔符。

最后我修复了它,它也适用于带有特殊符号的路径。
希望它能帮助遇到同样问题的人。

/**
 * It loads the 'config.properties' file into a FileInputStream object.
 *
 * @return The FileInputStream object.
 */
private FileInputStream loadInputPropertiesFile() {
    FileInputStream input = null;

    // Let's load the properties file from the *.jar file parent folder...
    File jarPath = new File(PropertiesManagement.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    String propertiesPath = String.format("%s" + File.separator, jarPath.getParentFile().getAbsolutePath());
    propertiesPath = propertiesPath.replace("%20", "\u0020");

    try {   
        // ... and setting the pointer to the same path, ready to read the properties file.
        input = new FileInputStream(propertiesPath + CONFIG_FILE_PATH);
    } catch (FileNotFoundException e) {
        System.out.println("Properties file not found! Have you deleted it?");
        e.printStackTrace();
    }

    return input;
}