java拾遗:如何读取properties文件内容

2015-01-28

使用netbeans创建项目


首先使用netbeans 8创建java项目HelloJava,布局如下:

src目录保存着编写的代码,build保存编译好的class文件、资源文件等。

user.properties内容如下:

name=root
password=hi

使用绝对路径读取


类me.letian.HelloJava内容如下:

package me.letian;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;

public class HelloJava {

    public static void main(String[] args) throws IOException {
        Properties props = new Properties();
        String propsPath = "/home/letian/NetBeansProjects/HelloJava/build/classes/me/letian/user.properties";

        try (InputStream in = Files.newInputStream(Paths.get(propsPath))) {
            props.load(in);
            System.out.println(props.getProperty("name"));
        }
    }
}

使用netbeans执行该类中的main方法,结果如下:

root

打包成jar文件:在菜单“Run”中选择“Clean and Build Project”,将会把项目打包成jar并放在项目下的dist目录下。

$ cd /home/letian/NetBeansProjects/HelloJava/dist/
$ jar tvf HelloJava.jar  # 查看jar内容
     0 Wed Jan 28 21:01:16 CST 2015 META-INF/
   210 Wed Jan 28 21:01:14 CST 2015 META-INF/MANIFEST.MF
     0 Wed Jan 28 21:01:16 CST 2015 me/
     0 Wed Jan 28 21:01:16 CST 2015 me/letian/
  2030 Wed Jan 28 21:01:16 CST 2015 me/letian/HelloJava.class
    21 Wed Jan 28 21:01:16 CST 2015 me/letian/user.properties
$ java -jar HelloJava.jar me.letian.HelloJava   # 执行
root

使用相对路径


使用相对路径,不能简单的将propsPath设值为user.properties

package me.letian;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;

public class HelloJava {

    public static void main(String[] args) throws IOException {
        Properties props = new Properties();
        String propsPath = "user.properties";

        System.out.println("" + Paths.get(propsPath).toAbsolutePath()); // 输出绝对路径

        try (InputStream in = Files.newInputStream(Paths.get(propsPath))) {
            props.load(in);
            System.out.println(props.getProperty("name"));
        }
    }
}

使用netbeans执行该类中的main方法,结果如下:

/home/letian/NetBeansProjects/HelloJava/user.properties
Exception in thread "main" java.nio.file.NoSuchFileException: user.properties
......

打包成jar并执行:

$ java -jar HelloJava.jar me.letian.HelloJava
/home/letian/NetBeansProjects/HelloJava/dist/user.properties
Exception in thread "main" java.nio.file.NoSuchFileException: user.properties
......

可以看到,上面的两种运行方式所输出的properties文件的绝对路径都是不存在的。

解决方法很简单:

String propsPath = "user.properties";

替换为

String propsPath = "src/me/letian/user.properties";

无论是使用绝对路径还是相对路径,对于jar都是不合适的,最好的方法是以资源文件的形式获取user.properties

以资源的形式(方法1)


package me.letian;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.Properties;

public class HelloJava {

    public static void main(String[] args) throws IOException {
        Properties props = new Properties();
        String propsPath = "me/letian/user.properties";

        try (InputStream in = HelloJava.class.getClassLoader().getResourceAsStream("me/letian/user.properties");) {
            props.load(in);
            System.out.println(props.getProperty("name"));
        }
    }
}

以资源的形式(方法2)


package me.letian;

import java.io.IOException;
import java.util.ResourceBundle;

public class HelloJava {

    public static void main(String[] args) throws IOException {

        ResourceBundle rb1 = ResourceBundle.getBundle("me.letian.user"); 
        System.out.println(rb1.getString("name")); 

        ResourceBundle rb2 = ResourceBundle.getBundle("me/letian/user"); 
        System.out.println(rb2.getString("password")); 
    }
}

执行结果:

root
hi
( 完 )