Đọc tệp thuộc tính trong Java


105

Tôi có đoạn mã sau đang cố gắng đọc tệp thuộc tính:

Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();           
InputStream stream = loader.getResourceAsStream("myProp.properties");
prop.load(stream);

Tôi nhận được một ngoại lệ ở dòng cuối cùng. Đặc biệt:

Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at Assignment1.BaseStation.readPropertyFile(BaseStation.java:46)
at Assignment1.BaseStation.main(BaseStation.java:87)

cảm ơn, Nikos

Câu trả lời:


89

Dựa trên ngoại lệ của bạn, InputStreamlà null, điều này có nghĩa là trình nạp lớp không tìm thấy tệp thuộc tính của bạn. Tôi đoán rằng myProp.properties nằm trong thư mục gốc của dự án của bạn, nếu đúng như vậy, bạn cần có dấu gạch chéo trước:

InputStream stream = loader.getResourceAsStream("/myProp.properties");

hệ thống phân cấp tệp của tôi là: src -> myPackage -> myClass.java, myProp.properties. Tôi đã làm những gì bạn đã khuyên tôi nhưng nó vẫn ném ra cùng một ngoại lệ
nikos

getResourceAsStreamtìm kiếm tệp trên đường dẫn classpath. Nếu tệp thuộc tính của bạn nằm trong thư mục gói của myPackage, thì hãy sử dụng /myPackage/myProp.propertieslàm đường dẫn.
Jesper

2
@Mark Elliot điều gì sẽ xảy ra nếu tôi có một confgói để lưu trữ tất cả các tệp cấu hình của mình và hệ thống phân cấp tệp của tôi là : myproject ->src, conf, test, Làm cách nào để tải các thuộc tính bằng cách thêm dấu gạch chéo trước?
Roger Ray

54


Bạn có thể tìm thông tin trên trang này:
http://www.mkyong.com/java/java-properties-file-examples/

Properties prop = new Properties();
try {
    //load a properties file from class path, inside static method
    prop.load(App.class.getClassLoader().getResourceAsStream("config.properties"));

    //get the property value and print it out
    System.out.println(prop.getProperty("database"));
    System.out.println(prop.getProperty("dbuser"));
    System.out.println(prop.getProperty("dbpassword"));

} 
catch (IOException ex) {
    ex.printStackTrace();
}

3
Đừng quên để đóng Readertrong prop.load(reader), theo các tài liệu:The specified stream remains open after this method returns
Evandro Silva

25

Bạn có thể sử dụng ResourceBundlelớp để đọc tệp thuộc tính.

ResourceBundle rb = ResourceBundle.getBundle("myProp.properties");

1
ResourceBundle rb = ResourceBundle.getBundle ("myProp");
mcolak

2
Cách tiếp cận này được khuyến khích cho i18n.
khác

15
Properties prop = new Properties();

try {
    prop.load(new FileInputStream("conf/filename.properties"));
} catch (IOException e) {
    e.printStackTrace();
}

conf/filename.properties dựa trên dir gốc của dự án


7

Bạn không thể sử dụng từ khóa này như -

props.load(this.getClass().getResourceAsStream("myProps.properties"));

trong bối cảnh tĩnh.

Điều tốt nhất là nắm được ngữ cảnh ứng dụng như -

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/app-context.xml");

thì bạn có thể tải tệp tài nguyên từ classpath -

//load a properties file from class path, inside static method
        prop.load(context.getClassLoader().getResourceAsStream("config.properties"));

Điều này sẽ hoạt động cho cả ngữ cảnh tĩnh và không tĩnh và phần tốt nhất là tệp thuộc tính này có thể nằm trong bất kỳ gói / thư mục nào có trong classpath của ứng dụng.


4
ApplicationContext chỉ khả dụng trong trường hợp ứng dụng Spring
joro

6

Tệp của bạn sẽ có sẵn như com/example/foo/myProps.propertiestrong classpath. Sau đó tải nó dưới dạng:

props.load(this.getClass().getResourceAsStream("myProps.properties"));

4

nếu config.properties của bạn không nằm trong thư mục src / main / resource và nó nằm trong thư mục gốc của dự án thì bạn cần phải làm như sau: -

Properties prop = new Properties();          
File configFile = new File(myProp.properties);
InputStream stream = new FileInputStream(configFile);
prop.load(stream);

3

Đảm bảo rằng tên tệp chính xác và tệp thực sự nằm trong đường dẫn lớp. getResourceAsStream()sẽ trả về null nếu đây không phải là trường hợp khiến dòng cuối cùng ném ra ngoại lệ.

Nếu myProp.properties nằm trong thư mục gốc của dự án của bạn, hãy sử dụng /myProp.propertiesthay thế.


hệ thống phân cấp tệp của tôi là: src -> myPackage -> myClass.java, myProp.properties. Tôi đã làm những gì bạn đã khuyên tôi nhưng nó vẫn ném ra cùng một ngoại lệ
nikos

Vì tệp thuộc tính của bạn không nằm ở gốc của dự án nên bạn không cần dấu gạch chéo ở đầu.
mort

Tôi đã nhận được ngoại lệ ngay từ đầu mà không có dấu gạch chéo đầu tiên. Nó vẫn không hoạt động.
nikos

3

Bạn có thể sử dụng java.io.InputStream để đọc tệp như hình dưới đây:

InputStream inputStream = getClass().getClassLoader().getResourceAsStream(myProps.properties); 

Làm thế nào để chuyển đổi InputStream sang File trong java? Tôi muốn đọc .properties tập cách sử dụng File API

3

Với bối cảnh loader.getResourceAsStream("myPackage/myProp.properties")nên được sử dụng.

Dẫn đầu '/'không hoạt động với ClassLoader.getResourceAsStream(String)phương pháp.

Ngoài ra, bạn có thể sử dụng Class.getResourceAsStream(String)phương thức, dùng '/'để xác định xem đường dẫn là tuyệt đối hay liên quan đến vị trí lớp.

Ví dụ:

myClass.class.getResourceAsStream("myProp.properties")
myClass.class.getResourceAsStream("/myPackage/myProp.properties")

2

Nếu đường dẫn tệp thuộc tính của bạn và đường dẫn lớp java của bạn giống nhau thì bạn nên làm như vậy.

Ví dụ:

src / myPackage / MyClass.java

src / myPackage / MyFile.properties

Properties prop = new Properties();
InputStream stream = MyClass.class.getResourceAsStream("MyFile.properties");
prop.load(stream);

2

Không có câu trả lời hiện tại nào cho thấy InputStreamđang bị đóng (điều này sẽ làm rò rỉ bộ mô tả tệp) và / hoặc không giải quyết việc .getResourceAsStream()trả về null khi không tìm thấy tài nguyên (điều này sẽ dẫn đến một NullPointerExceptionthông báo khó hiểu, "inStream parameter is null"). Bạn cần những thứ như sau:

String propertiesFilename = "server.properties";
Properties prop = new Properties();
try (var inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilename)) {
    if (inputStream == null) {
        throw new FileNotFoundException(propertiesFilename);
    }
    prop.load(inputStream);
} catch (IOException e) {
    throw new RuntimeException(
                "Could not read " + propertiesFilename + " resource file: " + e);
}

1

Đối với tệp Thuộc tính đọc với thứ tự ban đầu của nó:

    File file = new File("../config/edc.properties");
    PropertiesConfiguration config = new PropertiesConfiguration();
    PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
    layout.load(new InputStreamReader(new FileInputStream(file)));

    for(Object propKey : layout.getKeys()){
        PropertiesConfiguration propval =  layout.getConfiguration();
        String value = propval.getProperty((String) propKey).toString();
        out.print("Current Key:" + propkey + "Current Value:" + propval + "<br>");
    }

1

Nhiều câu trả lời ở đây mô tả các phương thức nguy hiểm trong đó chúng khởi tạo luồng đầu vào tệp nhưng không nhận được tham chiếu đến luồng đầu vào để đóng luồng sau đó. Điều này dẫn đến các luồng đầu vào lơ lửng và rò rỉ bộ nhớ. Cách tải các thuộc tính chính xác phải tương tự như sau:

    Properties prop = new Properties();
    try(InputStream fis = new FileInputStream("myProp.properties")) {
        prop.load(fis);
    }
    catch(Exception e) {
        System.out.println("Unable to find the specified properties file");
        e.printStackTrace();
        return;
    }

Lưu ý việc khởi tạo luồng đầu vào tệp trong try-with-resourceskhối. Vì a FileInputStreamcó thể tự động đóng, nên nó sẽ tự động bị đóng sau khi try-with-resourceskhối được thoát. Nếu bạn muốn sử dụng một trykhối đơn giản , bạn phải đóng nó một cách rõ ràng bằng cách sử dụng fis.close();trong finallykhối.


0

Tôi thấy rằng câu hỏi là một câu hỏi cũ. Nếu bất kỳ ai tình cờ gặp phải điều này trong tương lai, tôi nghĩ đây là một cách đơn giản để làm điều đó. Giữ tệp thuộc tính trong thư mục dự án của bạn.

        FileReader reader = new FileReader("Config.properties");

        Properties prop = new Properties();
        prop.load(reader);

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.