Làm thế nào để sử dụng các tệp thuộc tính Java?


219

Tôi có một danh sách các cặp khóa / giá trị của các giá trị cấu hình mà tôi muốn lưu trữ dưới dạng các tệp thuộc tính Java và sau đó tải và lặp qua.

Câu hỏi:

  • Tôi có cần lưu trữ tệp trong cùng một gói với lớp sẽ tải chúng không, hoặc có vị trí cụ thể nào mà nó sẽ được đặt không?
  • Tập tin có cần kết thúc trong bất kỳ phần mở rộng cụ thể nào không .txt không?
  • Làm thế nào tôi có thể tải tập tin trong mã
  • Và làm thế nào tôi có thể lặp qua các giá trị bên trong?

Câu trả lời:


245

Bạn có thể chuyển InputStream cho Thuộc tính, vì vậy tệp của bạn có thể ở bất kỳ đâu và được gọi là bất cứ thứ gì.

Properties properties = new Properties();
try {
  properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
  ...
}

Lặp lại như:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}

Giá trị nào được trả về khi khóa không có trong tệp thuộc tính?
Mitaksh Gupta

2
@MitakshGupta Nếu không tìm thấy thuộc tính có tên bạn đã chuyển trong tệp hoặc trong danh sách thuộc tính mặc định, nó sẽ truy xuất lại null. Xem Javadoc
drigoangelo

3
Làm thế nào để so sánh với properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); điều này là, getResourceAsStreamso với FileInputStream? ưu và nhược điểm?
Thufir

80
  • Bạn có thể lưu trữ các tập tin bất cứ nơi nào bạn muốn. Nếu bạn muốn giữ nó trong tệp jar của mình, bạn sẽ muốn sử dụng Class.getResourceAsStream()hoặc ClassLoader.getResourceAsStream()truy cập nó. Nếu nó trên hệ thống tập tin thì nó dễ hơn một chút.

  • Bất kỳ tiện ích mở rộng nào cũng được, mặc dù. Sản phẩm phổ biến hơn theo kinh nghiệm của tôi

  • Tải tệp bằng cách sử dụng Properties.load, chuyển qua một InputStreamhoặc StreamReadernếu bạn đang sử dụng Java 6. (Nếu bạn đang sử dụng Java 6, có lẽ tôi sẽ sử dụng UTF-8 và Readerthay vì mã hóa ISO-8859-1 mặc định cho luồng. )

  • Lặp lại thông qua nó khi bạn lặp qua một bình thường Hashtable( Propertiesxuất phát từ), ví dụ như sử dụng keySet(). Ngoài ra, bạn có thể sử dụng bảng liệt kê trả về propertyNames().


1
Cảm ơn Jon, điều tiếp theo tôi biết tôi sẽ tìm kiếm thứ gì đó trên joda và bạn cũng sẽ trả lời như vậy.
Ngọn lửa

27

Nếu bạn đặt tệp thuộc tính trong cùng gói với lớp Foo, bạn có thể dễ dàng tải nó với

new Properties().load(Foo.class.getResourceAsStream("file.properties"))

Cho rằng các thuộc tính mở rộng Hashtable, bạn có thể lặp lại các giá trị theo cách tương tự như trong Hashtable.

Nếu bạn sử dụng phần mở rộng * .properations, bạn có thể nhận được hỗ trợ trình soạn thảo, ví dụ: Eclipse có trình soạn thảo tệp thuộc tính.


5
Bạn có thể làm điều này - nhưng tôi không thích lưu trữ các tệp thuộc tính trong cùng một gói. Bạn kết thúc với các tệp thuộc tính trải rộng khắp nơi trong ứng dụng của bạn. Tôi muốn lưu trữ tất cả các tệp thuộc tính trong thư mục gốc của ứng dụng và tải chúng dưới dạng "class.getResourceAsStream (" \ file.properies ")" hoặc ở một số vị trí đã biết khác.
Nate

Nate, đó là sự thật. Tuy nhiên, trong một số trường hợp, vị trí được triển khai không được biết (ví dụ: mọi thứ của thành phần cụ thể của bạn được gói vào một số kho lưu trữ). Trong những trường hợp như vậy, có thể khá thuận tiện để nói 'nó với lớp đó, bất cứ nơi nào lớp đó kết thúc'. Ngoài ra, để tránh lây lan các tệp khắp nơi, một gói cấu hình có thể được sử dụng cho tất cả các tệp thuộc tính.
Fabian Steeg

1
Fabian, cả hai trường hợp này đều hoạt động với nhận xét của tôi - nó dựa trên đường dẫn lớp - không phải hệ thống tập tin.
Nate

2
Đối với bất kỳ ai đang cố gắng lấy ví dụ của Nate để làm việc - dấu gạch chéo ngược nên được thay thế bằng dấu gạch chéo về phía trước. Vì vậy, trong trường hợp này: 'class.getResourceAsStream ("/ file.properIES")'
hash_collision

12

Có nhiều cách để tạo và đọc propertiestệp:

  1. Lưu trữ các tập tin trong cùng một gói.
  2. Đề nghị .propertiesmở rộng tuy nhiên bạn có thể chọn của riêng bạn.
  3. Sử dụng đề tài các lớp học nằm ở java.utilgói => Properties, ListResourceBundle, ResourceBundlelớp học.
  4. Để đọc các thuộc tính, sử dụng iterator hoặc enumerator hoặc các phương thức trực tiếp của Propertieshoặc java.lang.Systemlớp.

ResourceBundle lớp học:

 ResourceBundle rb = ResourceBundle.getBundle("prop"); // prop.properties
 System.out.println(rb.getString("key"));

Properties lớp học:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));

Xin chào AVD, tại sao chúng ta chỉ cần .propertiesgia hạn? Có gì sai với việc gia hạn '.txt'? xin hãy giúp tôi
atish shimpi

@atishshimpi Không bắt buộc khi làm việc với loại Thuộc tính nhưng bắt buộc đối với ResourceBundle - đọc doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost

5

Điều này tải tập tin thuộc tính:

Properties prop = new Properties();
InputStream stream = ...; //the stream to the file
try {
  prop.load(stream);
} finally {
  stream.close();
}

Tôi sử dụng để đặt tệp .properIES trong một thư mục chứa tất cả các tệp cấu hình, tôi không đặt nó cùng với lớp truy cập vào nó, nhưng không có hạn chế nào ở đây.

Đối với tên ... Tôi sử dụng .properations cho mục đích dài dòng, tôi không nghĩ bạn nên đặt tên cho nó. Sản phẩm nếu bạn không muốn.


Tuy nhiên, một số "phần mở rộng" của các tệp thuộc tính giả định phần mở rộng .properations - ví dụ ResourceBundle được sử dụng trong I18N.
Nate

5

Thí dụ:

Properties pro = new Properties();
FileInputStream in = new FileInputStream("D:/prop/prop.properties");
pro.load(in);
String temp1[];
String temp2[];
// getting values from property file
String username = pro.getProperty("usernamev3");//key value in prop file 
String password = pro.getProperty("passwordv3");//eg. username="zub"
String delimiter = ",";                         //password="abc"
temp1=username.split(delimiter);
temp2=password.split(delimiter);

Điều gì nếu bạn có 3 tập tin propries?
Angelina

4

Tài sản đã trở thành di sản. Lớp Preferences được ưu tiên cho Properties.

Một nút trong bộ sưu tập dữ liệu ưu tiên phân cấp. Lớp này cho phép các ứng dụng lưu trữ và truy xuất dữ liệu cấu hình và ưu tiên của người dùng và hệ thống. Dữ liệu này được lưu trữ liên tục trong một cửa hàng sao lưu phụ thuộc vào việc thực hiện. Các triển khai điển hình bao gồm các tệp phẳng, đăng ký dành riêng cho hệ điều hành, máy chủ thư mục và cơ sở dữ liệu SQL. Người dùng của lớp này không cần phải quan tâm đến các chi tiết của cửa hàng sao lưu.

Không giống như các thuộc tính là các cặp khóa-giá trị dựa trên chuỗi, PreferencesLớp có một số phương thức được sử dụng để lấy và đưa dữ liệu nguyên thủy vào kho lưu trữ dữ liệu Tùy chọn. Chúng tôi chỉ có thể sử dụng các loại dữ liệu sau:

  1. Chuỗi
  2. boolean
  3. gấp đôi
  4. Phao nổi
  5. int
  6. Dài
  7. mảng byte

Để tải tệp thuộc tính, bạn có thể cung cấp đường dẫn tuyệt đối Hoặc sử dụng getResourceAsStream()nếu tệp thuộc tính có trong đường dẫn lớp của bạn.

package com.mypack.test;

import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;

public class PreferencesExample {

    public static void main(String args[]) throws FileNotFoundException {
        Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
        // Load file object
        File fileObj = new File("d:\\data.xml");
        try {
            FileInputStream fis = new FileInputStream(fileObj);
            ps.importPreferences(fis);
            System.out.println("Prefereces:"+ps);
            System.out.println("Get property1:"+ps.getInt("property1",10));

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

tập tin xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
  <map />
  <node name="mypack">
    <map />
    <node name="test">
      <map>
        <entry key="property1" value="80" />
        <entry key="property2" value="Red" />
      </map>
    </node>
  </node>
</node>
</root>
</preferences>

Hãy xem bài viết này về nội bộ của cửa hàng ưu đãi


3

Theo thứ tự:

  1. Bạn có thể lưu trữ các tập tin khá nhiều ở bất cứ đâu.
  2. không cần gia hạn.
  3. Montecristo đã minh họa làm thế nào để tải cái này. Điều đó sẽ làm việc tốt.
  4. propertyNames () cung cấp cho bạn một phép liệt kê để lặp qua.

2. no extension is necessary, Bạn có thể vui lòng cung cấp cho tôi bất kỳ tài liệu tham khảo cho tuyên bố này xin vui lòng. Tôi có nhầm lẫn về điều đó.
atish shimpi

Lưu ý rằng bạn có thể tải các thuộc tính thông qua một luồng đầu vào. Do đó, các thuộc tính không có kiến ​​thức về nguồn đầu vào đó đến từ đâu (một tệp? Ổ cắm?) Và do đó không thể thực thi một tiêu chuẩn đặt tên
Brian Agnew

3

Theo mặc định, Java mở nó trong thư mục làm việc của ứng dụng của bạn (hành vi này thực sự phụ thuộc vào HĐH được sử dụng). Để tải một tập tin, hãy làm:

Properties props = new java.util.Properties();
FileInputStream fis new FileInputStream("myfile.txt");
props.load(fis)

Như vậy, bất kỳ phần mở rộng tập tin có thể được sử dụng cho tập tin thuộc tính. Ngoài ra, tệp cũng có thể được lưu trữ ở bất cứ đâu, miễn là bạn có thể sử dụng a FileInputStream.

Trên một lưu ý liên quan nếu bạn sử dụng một khung hiện đại, khung này có thể cung cấp các cách bổ sung để mở tệp thuộc tính. Ví dụ, Spring cung cấp một ClassPathResourceđể tải tệp thuộc tính bằng tên gói từ bên trong tệp JAR.

Đối với việc lặp qua các thuộc tính, một khi các thuộc tính được tải, chúng được lưu trữ trong java.util.Propertiesđối tượng, cung cấp propertyNames()phương thức.


3

Đọc tệp thuộc tính và tải nội dung của nó vào Properties

String filename = "sample.properties";
Properties properties = new Properties();

input = this.getClass().getClassLoader().getResourceAsStream(filename);
properties.load(input);

Sau đây là cách hiệu quả để lặp lại qua một Properties

    for (Entry<Object, Object> entry : properties.entrySet()) {

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }

3

Trong Java 8 để có được tất cả các thuộc tính của bạn

public static Map<String, String> readPropertiesFile(String location) throws Exception {

    Map<String, String> properties = new HashMap<>();

    Properties props = new Properties();
    props.load(new FileInputStream(new File(location)));

    props.forEach((key, value) -> {
        properties.put(key.toString(), value.toString());
    });

    return properties;
}

2

1) Thật tốt khi có tệp tài sản của bạn trong classpath nhưng bạn có thể đặt nó ở bất cứ đâu trong dự án.

Dưới đây là cách bạn tải tệp thuộc tính từ classpath và đọc tất cả các thuộc tính.

Properties prop = new Properties();
InputStream input = null;

try {

    String filename = "path to property file";
    input = getClass().getClassLoader().getResourceAsStream(filename);
    if (input == null) {
        System.out.println("Sorry, unable to find " + filename);
        return;
    }

    prop.load(input);

    Enumeration<?> e = prop.propertyNames();
    while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        String value = prop.getProperty(key);
        System.out.println("Key : " + key + ", Value : " + value);
    }

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    if (input != null) {
        try {
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2) Tệp thuộc tính có phần mở rộng là .properations


1

Đây là một cách khác để lặp lại các thuộc tính:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}

2
Tôi hoàn toàn xin lỗi. Tôi đã xem lại mã trong câu trả lời của Zed và nó hoạt động khá tốt ... Tôi không biết tôi nghĩ gì khi đó ... Thật ra giải pháp của anh ấy đẹp hơn tôi, tôi nghĩ ...
dertoni

1

Tôi đã viết trên khung tài sản này cho năm ngoái. Nó sẽ cung cấp nhiều cách để tải các thuộc tính và chúng cũng được gõ mạnh.

Hãy xem http://sourceforge.net/projects/jhpropertiestyp/

JHProperIESTyped sẽ cung cấp cho nhà phát triển các thuộc tính được gõ mạnh. Dễ dàng tích hợp trong các dự án hiện có. Xử lý một loạt lớn cho các loại tài sản. Cung cấp khả năng khởi tạo các thuộc tính một dòng thông qua triển khai IO thuộc tính. Cung cấp cho nhà phát triển khả năng tạo các loại tài sản và tài sản của riêng tôi. Web demo cũng có sẵn, ảnh chụp màn hình hiển thị ở trên. Cũng có một triển khai tiêu chuẩn cho giao diện người dùng web để quản lý các thuộc tính, nếu bạn chọn sử dụng nó.

Toàn bộ tài liệu, hướng dẫn, javadoc, faq, vv có sẵn trên trang web của dự án.


0

Ở đây lớp tĩnh sẵn sàng

import java.io.*;
import java.util.Properties;
public class Settings {
    public static String Get(String name,String defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return props.getProperty(name);
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Integer Get(String name,Integer defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Integer.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Boolean Get(String name,Boolean defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Boolean.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static void Set(String name, String value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer, Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Integer value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Boolean value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
}

Dưới đây là mẫu:

Settings.Set("valueName1","value");
String val1=Settings.Get("valueName1","value");
Settings.Set("valueName2",true);
Boolean val2=Settings.Get("valueName2",true);
Settings.Set("valueName3",100);
Integer val3=Settings.Get("valueName3",100);

0

Bạn có thể tải tập tin tài sản kiện theo cách sau:

InputStream is = new Test().getClass().getClassLoader().getResourceAsStream("app.properties");
        Properties props =  new Properties();
        props.load(is);

Và sau đó bạn có thể lặp lại trên bản đồ bằng biểu thức lambda như:

props.stringPropertyNames().forEach(key -> {
            System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
        });

0

theo ý kiến ​​của tôi, những cách khác không được chấp nhận khi chúng ta có thể làm điều đó rất đơn giản như sau:

@PropertySource("classpath:application.properties")
public class SomeClass{

    @Autowired
    private Environment env;

    public void readProperty() {
        env.getProperty("language");
    }

}

nó rất đơn giản nhưng tôi nghĩ đó là cách tốt nhất !! Thưởng thức

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.