จะใช้ไฟล์คุณสมบัติ Java ได้อย่างไร


219

ฉันมีรายการคู่คีย์ / ค่าของค่าการตั้งค่าที่ฉันต้องการจัดเก็บเป็นไฟล์คุณสมบัติ Java และหลังจากนั้นโหลดและวนซ้ำผ่าน

คำถาม:

  • ฉันต้องจัดเก็บไฟล์ในแพ็คเกจเดียวกันกับคลาสที่จะโหลดหรือไม่หรือมีตำแหน่งเฉพาะที่ควรวางไว้หรือไม่?
  • ไฟล์จำเป็นต้องสิ้นสุดในส่วนขยายเฉพาะหรือ.txtตกลงหรือไม่?
  • ฉันจะโหลดไฟล์ในรหัสได้อย่างไร
  • และฉันจะทำซ้ำผ่านค่าภายในได้อย่างไร

คำตอบ:


246

คุณสามารถส่ง InputStream ไปยัง Property ได้ดังนั้นไฟล์ของคุณจะอยู่ที่ใดก็ได้และเรียกว่าอะไรก็ได้

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

พูดซ้ำเป็น:

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

ค่าใดที่ถูกส่งคืนเมื่อไม่มีคีย์ในไฟล์คุณสมบัติ
Mitaksh Gupta

2
@MitakshGupta หากไม่พบคุณสมบัติที่มีชื่อที่คุณผ่านในไฟล์หรือในรายการคุณสมบัติเริ่มต้นคุณสมบัตินั้นจะกลับมาnullอีกครั้ง ดูJavadoc
drigoangelo

3
สิ่งนี้เปรียบเทียบกับproperties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); สิ่งนั้นได้อย่างไรgetResourceAsStreamเทียบกับFileInputStream? ข้อดีและข้อเสีย?
Thufir

80
  • คุณสามารถจัดเก็บไฟล์ได้ทุกที่ที่คุณต้องการ หากคุณต้องการเก็บไว้ในไฟล์ jar คุณจะต้องใช้Class.getResourceAsStream()หรือClassLoader.getResourceAsStream()เข้าถึง หากอยู่ในระบบไฟล์ก็จะง่ายขึ้นเล็กน้อย

  • ส่วนขยายใด ๆ ก็ได้ แต่คุณสมบัติของฉันนั้นเป็นเรื่องธรรมดาในประสบการณ์ของฉัน

  • โหลดไฟล์โดยใช้Properties.loadผ่านในInputStreamหรือStreamReaderถ้าคุณกำลังใช้ Java 6. (ถ้าคุณจะใช้ Java 6 ผมอาจจะใช้ UTF-8 และReaderแทนการเริ่มต้น ISO-8859-1 เข้ารหัสสำหรับสตรีม )

  • ย้ำผ่านได้ตามที่คุณต้องการย้ำผ่านปกติHashtable(ซึ่งPropertiesมาจาก) keySet()เช่นใช้ propertyNames()หรือคุณสามารถใช้การแจงนับกลับโดย


1
ขอบคุณจอนสิ่งต่อไปที่ฉันรู้ว่าฉันกำลังมองหาบางสิ่งบางอย่างใน joda และคุณจะตอบว่าเกินไป
Flame

27

หากคุณวางไฟล์คุณสมบัติไว้ในแพ็คเกจเดียวกันกับคลาส Foo คุณสามารถโหลดได้ง่าย

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

ระบุว่า Properties ขยาย Hashtable คุณสามารถวนซ้ำค่าในลักษณะเดียวกับที่คุณทำใน Hashtable

หากคุณใช้ส่วนขยาย * .properties คุณสามารถรับการสนับสนุนจากบรรณาธิการเช่น Eclipse มีโปรแกรมแก้ไขไฟล์คุณสมบัติ


5
คุณสามารถทำได้ - แต่ฉันไม่ชอบการจัดเก็บไฟล์คุณสมบัติในแพ็คเกจเดียวกัน คุณจบลงด้วยไฟล์คุณสมบัติกระจายไปทั่วสถานที่ในใบสมัครของคุณ ฉันต้องการเก็บไฟล์คุณสมบัติทั้งหมดไว้ในรูทของแอปและโหลดเป็น "class.getResourceAsStream (" \ file.properties ")" หรือในตำแหน่งอื่นที่รู้จัก
เนท

เนทนั่นจริง อย่างไรก็ตามในบางสถานการณ์ไม่ทราบตำแหน่งที่นำไปใช้งาน (เช่นทุกอย่างขององค์ประกอบเฉพาะของคุณจะรวมอยู่ในที่เก็บถาวร) ในกรณีเช่นนี้มันค่อนข้างสะดวกที่จะพูดว่า 'อยู่กับคลาสนั้นไม่ว่าคลาสนั้นจะจบลงที่ใด' นอกจากนี้เพื่อหลีกเลี่ยงการแพร่กระจายไฟล์ทั่วแพคเกจ config เดียวสามารถใช้สำหรับไฟล์คุณสมบัติทั้งหมด
Fabian Steeg

1
เฟเบียนทั้งสองกรณีทำงานร่วมกับความคิดเห็นของฉัน - มันขึ้นอยู่กับ classpath - ไม่ใช่ระบบไฟล์
เนท

2
สำหรับทุกคนที่พยายามให้ตัวอย่างของ Nate ทำงาน - เครื่องหมายแบ็กสแลชควรถูกแทนที่ด้วยเครื่องหมายสแลช ดังนั้นในกรณีนี้: 'class.getResourceAsStream ("/ file.properties")'
hash_collision

12

มีหลายวิธีในการสร้างและอ่านpropertiesไฟล์:

  1. จัดเก็บไฟล์ในแพ็คเกจเดียวกัน
  2. แนะนำ.propertiesส่วนขยาย แต่คุณสามารถเลือกได้เอง
  3. ใช้วิทยานิพนธ์เรียนอยู่ที่java.utilแพคเกจ => Properties, ListResourceBundle, ResourceBundleชั้นเรียน
  4. หากต้องการอ่านคุณสมบัติให้ใช้ตัววนซ้ำหรือตัวแจงนับหรือวิธีโดยตรงPropertiesหรือjava.lang.Systemคลาส

ResourceBundle ระดับ:

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

Properties ระดับ:

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

สวัสดี AVD เหตุใดเราจึงต้องการ.propertiesส่วนขยายเท่านั้น เกิดอะไรขึ้นกับส่วนขยาย '.txt' โปรดช่วยฉัน
atish shimpi

@atishshimpi ไม่จำเป็นขณะทำงานกับประเภท Properties แต่จำเป็นสำหรับ ResourceBundle - อ่าน doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost

5

สิ่งนี้จะโหลดไฟล์คุณสมบัติ:

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

ฉันใช้เพื่อใส่ไฟล์. properties ในไดเรกทอรีที่ฉันมีไฟล์การกำหนดค่าทั้งหมดฉันไม่ได้รวมมันกับคลาสที่เข้าถึงได้ แต่ไม่มีข้อ จำกัด ที่นี่

สำหรับชื่อ ... ฉันใช้. คุณสมบัติเพื่อ verbosity ฉันไม่คิดว่าคุณควรตั้งชื่อ. คุณสมบัติถ้าคุณไม่ต้องการ


อย่างไรก็ตาม "ส่วนขยาย" ของไฟล์คุณสมบัติถือว่าส่วนขยาย. properties - ตัวอย่างเช่น ResourceBundle ที่ใช้ใน I18N
เนท

5

ตัวอย่าง:

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);

ถ้าคุณมีไฟล์ proprties 3 ไฟล์ล่ะ?
แองเจลิน่า

4

คุณสมบัติได้กลายเป็นมรดก การตั้งค่าระดับเป็นที่ต้องการคุณสมบัติ

โหนดในการรวบรวมข้อมูลการกำหนดค่าตามลำดับชั้น คลาสนี้อนุญาตให้แอปพลิเคชันจัดเก็บและดึงข้อมูลผู้ใช้งานและการตั้งค่าระบบและข้อมูลการกำหนดค่า ข้อมูลนี้ถูกเก็บไว้อย่างต่อเนื่องในที่เก็บข้อมูลสำรองที่ขึ้นอยู่กับการนำไปใช้งาน การใช้งานทั่วไปรวมถึงไฟล์แบนการลงทะเบียนเฉพาะระบบปฏิบัติการเซิร์ฟเวอร์ไดเรกทอรีและฐานข้อมูล SQL ผู้ใช้ของคลาสนี้ไม่จำเป็นต้องกังวลกับรายละเอียดของที่เก็บข้อมูลสำรอง

ซึ่งแตกต่างจากคุณสมบัติซึ่งเป็นคู่คีย์ - ค่าตามสตริงPreferencesคลาสมีหลายวิธีที่ใช้ในการรับและวางข้อมูลดั้งเดิมในที่เก็บข้อมูลการตั้งค่า เราสามารถใช้ข้อมูลประเภทต่อไปนี้เท่านั้น:

  1. เชือก
  2. บูล
  3. สอง
  4. ลอย
  5. int
  6. ยาว
  7. อาร์เรย์ไบต์

ในการโหลดไฟล์คุณสมบัติคุณสามารถระบุพา ธ สัมบูรณ์หรือใช้getResourceAsStream()หากไฟล์คุณสมบัติมีอยู่ใน classpath ของคุณ

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();
        }
    }
}

ไฟล์ 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>

ดูที่บทความนี้เกี่ยวกับการจัดเก็บค่ากำหนดภายใน


3

ในการสั่งซื้อ:

  1. คุณสามารถจัดเก็บไฟล์ได้สวยทุกที่
  2. ไม่จำเป็นต้องมีการขยาย
  3. Montecristo ได้แสดงวิธีการโหลดสิ่งนี้ ที่ควรจะทำงานได้ดี
  4. propertyNames ()ให้การแจงนับเพื่อทำซ้ำ

2. no extension is necessaryคุณช่วยกรุณาให้ฉันอ้างอิงใด ๆ สำหรับคำสั่งนี้โปรด ฉันมีความสับสนในเรื่องนั้น
atish shimpi

โปรดทราบว่าคุณสามารถโหลดคุณสมบัติผ่านทางอินพุตสตรีม เนื่องจากคุณสมบัติดังกล่าวไม่มีความรู้ว่าอินพุตสตรีมนั้นมาจากไหน (ไฟล์“ ซ็อกเก็ต”) ดังนั้นจึงไม่สามารถบังคับใช้มาตรฐานการตั้งชื่อได้
Brian Agnew

3

ตามค่าเริ่มต้น Java จะเปิดในไดเรกทอรีการทำงานของแอปพลิเคชันของคุณ (ลักษณะการทำงานนี้ขึ้นอยู่กับระบบปฏิบัติการที่ใช้) หากต้องการโหลดไฟล์ให้ทำ:

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

ดังนั้นนามสกุลไฟล์ใด ๆ ที่สามารถใช้สำหรับไฟล์คุณสมบัติ FileInputStreamนอกจากนี้ไฟล์ยังสามารถเก็บไว้ที่ใดก็ได้ตราบใดที่คุณสามารถใช้

ในบันทึกที่เกี่ยวข้องถ้าคุณใช้กรอบงานที่ทันสมัยกรอบอาจให้วิธีการเพิ่มเติมนอกเหนือจากการเปิดไฟล์คุณสมบัติ ตัวอย่างเช่น Spring จัดให้มีClassPathResourceเพื่อโหลดไฟล์คุณสมบัติโดยใช้ชื่อแพ็กเกจจากภายในไฟล์ JAR

สำหรับการวนซ้ำผ่านคุณสมบัติเมื่อโหลดคุณสมบัติแล้วจะถูกเก็บไว้ในjava.util.Propertiesวัตถุซึ่งเสนอpropertyNames()วิธีการ


3

อ่านไฟล์คุณสมบัติและโหลดเนื้อหาลงใน Properties

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

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

ต่อไปนี้เป็นวิธีที่มีประสิทธิภาพในการวนซ้ำ Properties

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

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

3

ในJava 8เพื่อรับคุณสมบัติทั้งหมดของคุณ

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) เป็นการดีที่มีไฟล์คุณสมบัติของคุณใน classpath แต่คุณสามารถวางไว้ที่ใดก็ได้ในโครงการ

ด้านล่างเป็นวิธีที่คุณโหลดไฟล์คุณสมบัติจาก classpath และอ่านคุณสมบัติทั้งหมด

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) ไฟล์คุณสมบัติมีนามสกุลเป็น. properties


1

นี่เป็นอีกวิธีหนึ่งในการย้ำคุณสมบัติ

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

2
ฉันเสียใจอย่างยิ่ง ฉันตรวจสอบรหัสในคำตอบของ Zed และทำงานได้ค่อนข้างดี ... ฉันไม่รู้ว่าฉันคิดอย่างไรในตอนนั้น ... จริง ๆ แล้ววิธีแก้ปัญหาของเขาดีกว่าของฉันฉันคิดว่า ...
dertoni

1

ฉันได้เขียนเกี่ยวกับกรอบคุณสมบัตินี้สำหรับปีที่แล้ว มันจะให้หลายวิธีในการโหลดคุณสมบัติและให้พวกเขาพิมพ์อย่างยิ่งเช่นกัน

ดูที่http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped จะให้คุณสมบัติที่นักพัฒนาพิมพ์อย่างยิ่ง ง่ายต่อการรวมในโครงการที่มีอยู่ จัดการโดยชุดข้อมูลขนาดใหญ่สำหรับประเภทคุณสมบัติ ให้ความสามารถในการเริ่มต้นคุณสมบัติหนึ่งบรรทัดผ่านการใช้งาน IO คุณสมบัติ ให้นักพัฒนาสามารถสร้างประเภทของคุณสมบัติและคุณสมบัติของ io ได้ นอกจากนี้ยังมีตัวอย่างเว็บพร้อมภาพหน้าจอที่แสดงด้านบน นอกจากนี้ยังมีการนำมาตรฐานไปใช้สำหรับส่วนหน้าของเว็บเพื่อจัดการคุณสมบัติหากคุณเลือกที่จะใช้

เอกสารที่สมบูรณ์, การสอน, javadoc, คำถามที่พบบ่อยและอื่น ๆ สามารถใช้ได้บนหน้าเว็บโครงการ


0

ชั้นคงที่นี่พร้อม

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);
        }
    }
}

ตัวอย่างที่นี่:

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

คุณสามารถโหลดไฟล์คุณสมบัติ suing ด้วยวิธีต่อไปนี้:

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

จากนั้นคุณสามารถวนซ้ำแผนที่โดยใช้นิพจน์แลมบ์ดาเช่น:

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

0

ในความคิดของฉันวิธีอื่น ๆ จะเลิกเมื่อเราสามารถทำได้ง่ายมากดังต่อไปนี้:

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

    @Autowired
    private Environment env;

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

}

มันง่ายมาก แต่ฉันคิดว่านั่นเป็นวิธีที่ดีที่สุด !! สนุก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.