Sök…


Introduktion

Egenskapsobjektet innehåller nyckel- och värdeparret både som en sträng. Klassen java.util.Properties är underklassen till Hashtable.

Det kan användas för att få fastighetsvärde baserat på egendomsnyckeln. Egenskaper-klassen tillhandahåller metoder för att hämta data från egenskaper-filen och lagra data i egenskaper-filen. Dessutom kan den användas för att få systemegenskaper.

Fördel med egenskaper fil

Omkompilering krävs inte om information ändras från egenskapsfilen: Om någon information ändras från

Syntax

  • I en egenskapsfil:
  • nyckel = värde
  • #kommentar

Anmärkningar

Ett Egenskapsobjekt är en karta vars nycklar och värden är Strängar enligt konvention. Även om kartmetoderna kan användas för att få åtkomst till data, används de mer typsäkra metoderna getProperty , setProperty och stringPropertyNames i stället.

Egenskaper lagras ofta i Java-fastighetsfiler, som är enkla textfiler. Deras format dokumenteras noggrant i metoden Properties.load . Sammanfattningsvis:

  • Varje nyckel / värdeparet är en textrad med blanktecken, är lika med ( = ) eller kolon ( : ) mellan nyckeln och värdet. Lika eller kolon kan ha någon mängd vitrymd före och efter det, vilket ignoreras.
  • Ledande whitespace ignoreras alltid, efterföljande whitespace ingår alltid.
  • Ett bakstreck kan användas för att undkomma alla tecken (utom gement u ).
  • Ett bakslag i slutet av linjen indikerar att nästa rad är en fortsättning på den aktuella linjen. Som med alla linjer ignoreras emellertid ledande mellanrum i fortsättningsraden.
  • Precis som i Java-källkoden representerar \u följt av fyra hexadecimala siffror ett UTF-16-tecken.

De flesta ramverk, inklusive Java SE: s egna anläggningar som java.util.ResourceBundle, laddar fastighetsfiler som InputStreams. När du laddar en egendomsfil från en InputStream kan den filen bara innehålla ISO 8859-1-tecken (det vill säga tecken i intervallet 0–255). Alla andra tecken måste representeras som \u flykt. Du kan emellertid skriva en textfil i valfri kodning och använda native2ascii- verktyget (som medföljer varje JDK) för att göra det som slipper åt dig.

Om du laddar en fastighetsfil med din egen kod kan den vara i vilken kodning som helst, så länge du skapar en läsare (t.ex. en InputStreamReader ) baserad på motsvarande Charset . Du kan sedan ladda filen med last (Reader) istället för den gamla arvsmetoden (InputStream) -metoden.

Du kan också lagra egenskaper i en enkel XML-fil, vilket gör att filen i sig kan definiera kodningen. En sådan fil kan laddas med metoden loadFromXML . DTD som beskriver strukturen för sådana XML-filer finns på http://java.sun.com/dtd/properties.dtd .

Laddar egenskaper

Så här laddar du en fastighetsfil som medföljer din applikation:

public class Defaults {

    public static Properties loadDefaults() {
        try (InputStream bundledResource =
            Defaults.class.getResourceAsStream("defaults.properties")) {

            Properties defaults = new Properties();
            defaults.load(bundledResource);
            return defaults;
        } catch (IOException e) {
            // Since the resource is bundled with the application,
            // we should never get here.
            throw new UncheckedIOException(
                "defaults.properties not properly packaged"
                + " with application", e);
        }
    }

}

Egenskapsfiler förbehåll: efterföljande mellanrum

Titta närmare på dessa två fastighetsfiler som till synes är helt identiska:

ange bildbeskrivning här

förutom att de egentligen inte är identiska:

ange bildbeskrivning här

(skärmdumpar kommer från Notepad ++)

Eftersom efterföljande vitrymd bevaras skulle värdet på lastName vara "Smith" i det första fallet och "Smith " i det andra fallet.

Mycket sällan är det vad användare förväntar sig och en och kan bara spekulera varför detta är standardbeteendet för klassen Properties . Det är dock lätt att skapa en förbättrad version av Properties som löser problemet. Följande klass, TrimmedProperties , gör just det. Det är en drop-in ersättning för standardegenskaper.

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Map.Entry;
import java.util.Properties;

/**
 * Properties class where values are trimmed for trailing whitespace if the
 * properties are loaded from a file.
 *
 * <p>
 * In the standard {@link java.util.Properties Properties} class trailing
 * whitespace is always preserved. When loading properties from a file such
 * trailing whitespace is almost always <i>unintentional</i>. This class fixes
 * this problem. The trimming of trailing whitespace only takes place if the
 * source of input is a file and only where the input is line oriented (meaning
 * that for example loading from XML file is <i>not</i> changed by this class).
 * For this reason this class is almost in all cases a safe drop-in replacement
 * for the standard <tt>Properties</tt>
 * class.
 *
 * <p>
 * Whitespace is defined here as any of space (U+0020) or tab (U+0009).
 * * 
 */
public class TrimmedProperties extends Properties {

    /**
     * Reads a property list (key and element pairs) from the input byte stream.
     * 
     * <p>Behaves exactly as {@link java.util.Properties#load(java.io.InputStream) }
     * with the exception that trailing whitespace is trimmed from property values
     * if <tt>inStream</tt> is an instance of <tt>FileInputStream</tt>.
     * 
     * @see java.util.Properties#load(java.io.InputStream) 
     * @param inStream the input stream.
     * @throws IOException if an error occurred when reading from the input stream.
     */
    @Override
    public void load(InputStream inStream) throws IOException {
        if (inStream instanceof FileInputStream) {
            // First read into temporary props using the standard way
            Properties tempProps = new Properties();
            tempProps.load(inStream);
            // Now trim and put into target
            trimAndLoad(tempProps);
        } else {
            super.load(inStream);
        }
    }

    /**
     * Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format. 
     * 
     * <p>Behaves exactly as {@link java.util.Properties#load(java.io.Reader)}
     * with the exception that trailing whitespace is trimmed on property values
     * if <tt>reader</tt> is an instance of <tt>FileReader</tt>.
     * 
     * @see java.util.Properties#load(java.io.Reader) }
     * @param reader the input character stream.
     * @throws IOException if an error occurred when reading from the input stream.
     */
    @Override
    public void load(Reader reader) throws IOException {
        if (reader instanceof FileReader) {
            // First read into temporary props using the standard way
            Properties tempProps = new Properties();
            tempProps.load(reader);
            // Now trim and put into target
            trimAndLoad(tempProps);
        } else {
            super.load(reader);
        }
    }

    private void trimAndLoad(Properties p) {
        for (Entry<Object, Object> entry : p.entrySet()) {
            if (entry.getValue() instanceof String) {
                put(entry.getKey(), trimTrailing((String) entry.getValue()));
            } else {
                put(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Trims trailing space or tabs from a string.
     *
     * @param str
     * @return
     */
    public static String trimTrailing(String str) {
        if (str != null) {
            // read str from tail until char is no longer whitespace
            for (int i = str.length() - 1; i >= 0; i--) {
                if ((str.charAt(i) != ' ') && (str.charAt(i) != '\t')) {
                    return str.substring(0, i + 1);
                }
            }
        }
        return str;
    }
}

Spara egenskaper som XML

Lagring av egenskaper i en XML-fil

Det sätt på vilket du lagrar fastighetsfiler som XML-filer är mycket likt det du skulle lagra dem som .properties . Bara istället för att använda store() skulle du använda storeToXML() .

public void saveProperties(String location) throws IOException{
    // make new instance of properties
    Properties prop = new Properties();
    
    // set the property values
    prop.setProperty("name", "Steve");
    prop.setProperty("color", "green");
    prop.setProperty("age", "23");
    
    // check to see if the file already exists
    File file = new File(location);
    if (!file.exists()){
        file.createNewFile();
    }
    
    // save the properties
    prop.storeToXML(new FileOutputStream(file), "testing properties with xml");
}

När du öppnar filen kommer den att se ut så här.

skärmdump av den gjorda filen

Laddar egenskaper från en XML-fil

För att ladda den här filen som properties måste du anropa loadFromXML() istället för load() som du skulle använda med vanliga .propeties filer.

public static void loadProperties(String location) throws FileNotFoundException, IOException{
    // make new properties instance to load the file into
    Properties prop = new Properties();
    
    // check to make sure the file exists
    File file = new File(location);
    if (file.exists()){
        // load the file
        prop.loadFromXML(new FileInputStream(file));
        
        // print out all the properties
        for (String name : prop.stringPropertyNames()){
            System.out.println(name + "=" + prop.getProperty(name));
        }
    } else {
        System.err.println("Error: No file found at: " + location);
    }
}

När du kör den här koden får du följande i konsolen:

age=23
color=green
name=Steve


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow