运行Java的JAR拒绝加载同一目录中的文件

运行Java的JAR拒绝加载同一目录中的文件,java,file,file-io,properties,Java,File,File Io,Properties,快一点。我正在尝试部署一个程序,该程序包含以下代码。我想读取一个名为properties的属性文件 Properties props = new Properties(); InputStream is; // First try - loading from the current directory try { File f = new File("properties"); is = new FileInputStream(f); } catch (FileNotFound

快一点。我正在尝试部署一个程序,该程序包含以下代码。我想读取一个名为
properties
的属性文件

Properties props = new Properties();
InputStream is;
// First try - loading from the current directory
try {
    File f = new File("properties");
    is = new FileInputStream(f);
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace(System.err);
    is = null;
}
try {
    if (is == null) {
        // Try loading from classpath
        is = getClass().getResourceAsStream("properties");
    }
    //Load properties from the file (if found), else crash and burn.
    props.load(is);
} catch (IOException e) {
    e.printStackTrace(System.err);
}
当我通过Netbeans运行程序时,一切都很顺利

但是,当我自己运行JAR时,会出现两个异常

java.io.FileNotFoundException: properties (The system cannot find the file specified)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        .
        .
        .           
Exception in Application start method
Exception in Application stop method
java.lang.reflect.InvocationTargetException
        .
        .
        .
        (exception during props.load(is) because is == null)
java.io.FileNotFoundException:属性(系统找不到指定的文件)
在java.io.FileInputStream.open(本机方法)
位于java.io.FileInputStream。(未知源)
.
.
.           
应用程序启动方法中的异常
应用程序停止方法中的异常
java.lang.reflect.InvocationTargetException
.
.
.
(加载(is)过程中出现异常,因为is==null)
我正在运行“dist”文件夹中的文件。我尝试将属性文件放在jar所在的文件夹中,但没有结果。通常,
属性
文件位于根项目文件夹中


有什么想法吗?

您将文件作为资源来阅读(
getResourceAsStream(“属性”);
)。所以它必须在类路径中。可能直接在jar中,或者在添加到类路径的目录中


jar是一个zip文件,因此您可以使用7zip打开它,例如,将属性文件添加到jars根级别,然后重试。

由于这些注释,我基于jar的当前运行目录构建了一个绝对路径生成器。祝你们好运,伙计们

private String relativizer(String file) {
    URL url = RobotikosAnomologitos.class.getProtectionDomain().getCodeSource().getLocation();
    String urlString = url.toString();
    int firstSlash = urlString.indexOf("/");
    int targetSlash = urlString.lastIndexOf("/", urlString.length() - 2) + 1;

    return urlString.substring(firstSlash, targetSlash) + file;
}
因此,我的新文件读取结构是:

        Properties props = new Properties();
        InputStream is;
        // First try - loading from the current directory
        try {
            File f = new File("properties");
            is = new FileInputStream(f);
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace(System.err);
            is = null;
        }
        try {
            if (is == null) {
                // Try loading from classpath
                String pathToProps = relativizer("properties");       
                is = new FileInputStream(new File(pathToProps));
                //is = getClass().getResourceAsStream(pathToProps);
            }
            //Load properties from the file (if found), else crash and burn.
            props.load(is);
        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        // Finally parse the properties. 
        //code here, bla bla

尝试使用文件的绝对路径。当您从类路径请求文件时,请确保该文件确实位于类路径上,可以使用java VM选项的“-cp/some/dir”。另外,请尝试使用前导斜杠字符,以便请求的资源具有绝对路径,如“/properties”。如果仍然存在问题,请确认您正在使用的平台以及java VM启动选项和命令行。它应该位于运行
java
命令的目录中。否则它会查看Jar本身,这是您的第二个
try
。您希望它在文件系统或jar中找到它吗?如果要读取与当前目录相关的文件,该文件必须位于运行命令的目录中,而不一定是jar所在的目录;使用
getResourceAsStream
及相关方法时,需要确保资源加载程序能够找到它;也就是说,它必须在类路径中。除了手动将资源添加到JAR本身之外,还有一些方法可以指定在构建JAR所用的任何东西中包含资源文件(不过,我在Netbeans中不知道它们)。手动添加用于生产目的的资源是不可能的。我只是建议用一种快速的方法来检查它是否有效。嗯,默认情况下,Netbeans应该自动将资源文件打包到JAR中,只要它们位于源文件夹中某个位置的类路径上。我知道Eclipse有一些选项可以禁用此功能,或者使用构建脚本忽略非Java文件,但我不知道Netbeans中是否存在类似的麻烦。我认为他将属性文件放在项目的根文件夹中,而不是源文件夹中,Netbeans会自动将此文件夹添加到类路径中。但是在构建jar时,netbeans只将源文件夹(可能还有maven之类的资源文件夹)中的资源放入jar。但我不确定。我通常与Eclise或Maven(Gradle…)一起工作,这更有意义。这将起作用,但您没有从类路径加载props文件,只从jar所在的目录加载。在源代码中,您从类路径读取它。但是必须将类路径配置为文件所在的目录,或者将文件放入jar文件中。