从 jar 中读取属性文件

Read properties file from jar

我想读取 jar 文件中的属性文件。我读了很多关于这个的线程,但它并没有解决问题。我使用以下方法来做到这一点:

public InputStream getLanguageFile(String languageName) {
    languageName = languageName.replace(".properties", "");
    return MainClass.class.getResourceAsStream("/me/s3ns3iw00/resources/languages/" + languageName + ".properties");
}

我收到以下错误:

Exception in Application start method
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
        at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.nio.file.InvalidPathException: Illegal char <:> at index 4: file:\C:\Users\danie\Desktop\mcserverlauncher_resources\setup\mcserverlauncher.jar!\me\s3ns3iw00\resources\languages
        at sun.nio.fs.WindowsPathParser.normalize(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPath.parse(Unknown Source)
        at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
        at java.io.File.toPath(Unknown Source)
        at me.s3ns3iw00.windows.Welcome.<init>(Welcome.java:59)
        at me.s3ns3iw00.MainClass.start(MainClass.java:44)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
        at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null7(WinApplication.java:177)
        ... 1 more
Exception running application me.s3ns3iw00.MainClass

抱歉我的英语不好,感谢您的帮助!

getResourceAsStream 需要 ResourceFile 内的路径,无需提供您的项目文件夹路径。

public InputStream getLanguageFile(String languageName) throws URISyntaxException {
    languageName = languageName.replace(".properties", "");
    return MainClass.class.getResourceAsStream("languages\" + languageName + ".properties");
}

所以我找到了解决方案。

我使用此方法获取文件的 InputStream 是什么在您的应用程序的 jar 中:

public InputStream getLanguageStream(String languageName) {
        languageName = languageName.replace(".properties", "");
        return MainClass.class.getResourceAsStream("/me/s3ns3iw00/resources/languages/" + languageName + ".properties");
}

现在您可以将其加载到属性中:

properties.load(new InputStreamReader(getLanguageStream("ENG"), Charset.forName("UTF-8")));

还有一个额外的:

我使用此方法获取 jar 路径中的文件名:

public List<String> getFileNamesInJarPath(String jarPath) {
        List<String> fileNames = new ArrayList<>();
        CodeSource src = MainClass.class.getProtectionDomain().getCodeSource();
        try {
            if (src != null) {
                URL jar = src.getLocation();
                ZipInputStream zip = new ZipInputStream(jar.openStream());
                while (true) {
                    ZipEntry e = zip.getNextEntry();
                    if (e == null)
                        break;
                    String name = e.getName();
                    if (name.startsWith(jarPath)) {
                        String substringedName = name.substring(name.lastIndexOf("/") + 1);
                        if (!substringedName.equalsIgnoreCase("")) {
                            fileNames.add(substringedName);
                        }
                    }
                }
            } else {
                /* Fail... */
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileNames;
}

您会得到一个 jarPath 目录内容的列表,您的应用程序的 jar 中有哪些内容。