当前位置: 首页 > news >正文

java properties 冒号_java集合(四)Map集合之Properties详解

一、Properties类介绍

java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动。从http://docs.oracle.com/javase/7/docs/api/的jdk7的官方api文档中我们可以看到对Properties类的介绍。Properties class是一个持久化的属性保存对象,可以将属性内容写出到stream中或者从stream中读取属性内容,在底层的Hashtable中,每一对属性的key和value都是按照string类型来保存的。 Properties可以将其他的Properties对象作为默认的值,Properties继承自Hashtable,所以Hashtable的所有方法Properties对象均可以访问。

Properties支持文本方式和xml方式的数据存储。在文本方式中,格式为key:value,其中分隔符可以是:冒号(:)、等号(=)、空格。其中空格可以作为key的结束,同时获取的值回将分割符号两端的空格去掉。

Properties只支持1对1模式的属性设置,而且不支持多层多级属性设置。

二、Properties类属性

protected Properties defaults:包含默认values的Properties对象,默认为null。我们在找不到对应key的情况下,就回递归的从这个默认列表中里面来找。

/**

* A property list that contains default values for any keys not

* found in this property list.

*

* @serial*/

protectedProperties defaults;

Properties property

三、初始化方法

Properties提供两种方式来创建Properties对象,第一种是不指定默认values对象的创建方法,另外一种是指定默认values对象的创建方法。但是此时是没有加载属性值的,加载key/value属性必须通过专门的方法来加载。

/**

* Creates an empty property list with no default values.*/

publicProperties() {this(null);

}/**

* Creates an empty property list with the specified defaults.

*

* @param defaults the defaults.*/

publicProperties(Properties defaults) {this.defaults =defaults;

}

Properties Construction Method

四、常用方法

getProperty(String):根据指定的key获取对应的属性value值,如果在自身的存储集合中没有找到对应的key,那么就直接到默认的defaults属性指定的Properties中获取属性值。

/**

* Searches for the property with the specified key in this property list.

* If the key is not found in this property list, the default property list,

* and its defaults, recursively, are then checked. The method returns

* null if the property is not found.

*

* @param key the property key.

* @return the value in this property list with the specified key value.

* @see #setProperty

* @see #defaults*/

publicString getProperty(String key) {

Object oval= super.get(key);

String sval= (oval instanceof String) ? (String)oval : null;return ((sval == null) && (defaults != null)) ?defaults.getProperty(key) : sval;

}

getProperty(String)

getProperty(String, String):当getProperty(String)方法返回值为null的时候,返回给定的默认值,而不是返回null。

/**

* Searches for the property with the specified key in this property list.

* If the key is not found in this property list, the default property list,

* and its defaults, recursively, are then checked. The method returns the

* default value argument if the property is not found.

*

* @param key the hashtable key.

* @param defaultValue a default value.

*

* @return the value in this property list with the specified key value.

* @see #setProperty

* @see #defaults*/

publicString getProperty(String key, String defaultValue) {

String val=getProperty(key);return (val == null) ?defaultValue : val;

}

getProperty(String,String)

load(InputStream):从byte stream中加载key/value键值对,要求所有的key/value键值对是按行存储,同时是用ISO-8859-1编译的。

/**

* Reads a property list (key and element pairs) from the input

* byte stream. The input stream is in a simple line-oriented

* format as specified in

* {@link #load(java.io.Reader) load(Reader)} and is assumed to use

* the ISO 8859-1 character encoding; that is each byte is one Latin1

* character. Characters not in Latin1, and certain special characters,

* are represented in keys and elements using Unicode escapes as defined in

* section 3.3 of

* The Java™ Language Specification.

*

* The specified stream remains open after this method returns.

*

* @param inStream the input stream.

* @exception IOException if an error occurred when reading from the

* input stream.

* @throws IllegalArgumentException if the input stream contains a

* malformed Unicode escape sequence.

* @since 1.2*/

public synchronized voidload(InputStream inStream) throws IOException {

load0(newLineReader(inStream));

}

load(InputStream)

load(Reader):从字符流中加载key/value键值对,要求所有的键值对都是按照行来存储的。

/**

* Reads a property list (key and element pairs) from the input

* character stream in a simple line-oriented format.

*

* Properties are processed in terms of lines. There are two

* kinds of line, natural lines and logical lines.

* A natural line is defined as a line of

* characters that is terminated either by a set of line terminator

* characters (\n or \r or \r\n)

* or by the end of the stream. A natural line may be either a blank line,

* a comment line, or hold all or some of a key-element pair. A logical

* line holds all the data of a key-element pair, which may be spread

* out across several adjacent natural lines by escaping

* the line terminator sequence with a backslash character

* \. Note that a comment line cannot be extended

* in this manner; every natural line that is a comment must have

* its own comment indicator, as described below. Lines are read from

* input until the end of the stream is reached.

*

*

* A natural line that contains only white space characters is

* considered blank and is ignored. A comment line has an ASCII

* '#' or '!' as its first non-white

* space character; comment lines are also ignored and do not

* encode key-element information. In addition to line

* terminators, this format considers the characters space

* (' ', '\u0020'), tab

* ('\t', '\u0009'), and form feed

* ('\f', '\u000C') to be white

* space.

*

*

* If a logical line is spread across several natural lines, the

* backslash escaping the line terminator sequence, the line

* terminator sequence, and any white space at the start of the

* following line have no affect on the key or element values.

* The remainder of the discussion of key and element parsing

* (when loading) will assume all the characters constituting

* the key and element appear on a single natural line after

* line continuation characters have been removed. Note that

* it is not sufficient to only examine the character

* preceding a line terminator sequence to decide if the line

* terminator is escaped; there must be an odd number of

* contiguous backslashes for the line terminator to be escaped.

* Since the input is processed from left to right, a

* non-zero even number of 2n contiguous backslashes

* before a line terminator (or elsewhere) encodes n

* backslashes after escape processing.

*

*

* The key contains all of the characters in the line starting

* with the first non-white space character and up to, but not

* including, the first unescaped '=',

* ':', or white space character other than a line

* terminator. All of these key termination characters may be

* included in the key by escaping them with a preceding backslash

* character; for example,

*

* \:\=

*

* would be the two-character key ":=". Line

* terminator characters can be included using \r and

* \n escape sequences. Any white space after the

* key is skipped; if the first non-white space character after

* the key is '=' or ':', then it is

* ignored and any white space characters after it are also

* skipped. All remaining characters on the line become part of

* the associated element string; if there are no remaining

* characters, the element is the empty string

* "". Once the raw character sequences

* constituting the key and element are identified, escape

* processing is performed as described above.

*

*

* As an example, each of the following three lines specifies the key

* "Truth" and the associated element value

* "Beauty":

*

*


 

* Truth = Beauty

* Truth:Beauty

* Truth :Beauty

*

* As another example, the following three lines specify a single

* property:

*

*


 

* fruits apple, banana, pear, \

* cantaloupe, watermelon, \

* kiwi, mango

*

* The key is "fruits" and the associated element is:

*

*

"apple, banana, pear, cantaloupe, watermelon, kiwi, mango"

* Note that a space appears before each \ so that a space

* will appear after each comma in the final result; the \,

* line terminator, and leading white space on the continuation line are

* merely discarded and are not replaced by one or more other

* characters.

*

* As a third example, the line:

*

*

cheeses

*

* specifies that the key is "cheeses" and the associated

* element is the empty string "".

*

*

*

* Characters in keys and elements can be represented in escape

* sequences similar to those used for character and string literals

* (see sections 3.3 and 3.10.6 of

* The Java™ Language Specification).

*

* The differences from the character escape sequences and Unicode

* escapes used for characters and strings are:

*

*

*

Octal escapes are not recognized.

*

*

The character sequence \b does not

* represent a backspace character.

*

*

The method does not treat a backslash character,

* \, before a non-valid escape character as an

* error; the backslash is silently dropped. For example, in a

* Java string the sequence "\z" would cause a

* compile time error. In contrast, this method silently drops

* the backslash. Therefore, this method treats the two character

* sequence "\b" as equivalent to the single

* character 'b'.

*

*

Escapes are not necessary for single and double quotes;

* however, by the rule above, single and double quote characters

* preceded by a backslash still yield single and double quote

* characters, respectively.

*

*

Only a single 'u' character is allowed in a Uniocde escape

* sequence.

*

*

*

* The specified stream remains open after this method returns.

*

* @param reader the input character stream.

* @throws IOException if an error occurred when reading from the

* input stream.

* @throws IllegalArgumentException if a malformed Unicode escape

* appears in the input.

* @since 1.6*/

public synchronized voidload(Reader reader) throws IOException {

load0(newLineReader(reader));

}

load(Reader)

loadFromXML(InputStream):从xml文件中加载property,底层使用XMLUtils.load(Properties,InputStream)方法来加载。

/**

* Loads all of the properties represented by the XML document on the

* specified input stream into this properties table.

*

*

The XML document must have the following DOCTYPE declaration:

*


 

* <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

*

* Furthermore, the document must satisfy the properties DTD described

* above.

*

*

The specified stream is closed after this method returns.

*

* @param in the input stream from which to read the XML document.

* @throws IOException if reading from the specified input stream

* results in an IOException.

* @throws InvalidPropertiesFormatException Data on input stream does not

* constitute a valid XML document with the mandated document type.

* @throws NullPointerException if in is null.

* @see #storeToXML(OutputStream, String, String)

* @since 1.5*/

public synchronized void loadFromXML(InputStream in)

throws IOException, InvalidPropertiesFormatException

{if (in == null)throw newNullPointerException();

XMLUtils.load(this, in);in.close();

}

loadFromXML(InputStream)

store(OutputStream/Writer,comments)将所有的property(保存defaults的)都写出到流中,同时如果给定comments的话,那么要加一个注释。

/**

* Writes this property list (key and element pairs) in this

* Properties table to the output character stream in a

* format suitable for using the {@link #load(java.io.Reader) load(Reader)}

* method.

*

* Properties from the defaults table of this Properties

* table (if any) are not written out by this method.

*

* If the comments argument is not null, then an ASCII #

* character, the comments string, and a line separator are first written

* to the output stream. Thus, the comments can serve as an

* identifying comment. Any one of a line feed ('\n'), a carriage

* return ('\r'), or a carriage return followed immediately by a line feed

* in comments is replaced by a line separator generated by the Writer

* and if the next character in comments is not character # or

* character ! then an ASCII # is written out

* after that line separator.

*

* Next, a comment line is always written, consisting of an ASCII

* # character, the current date and time (as if produced

* by the toString method of Date for the

* current time), and a line separator as generated by the Writer.

*

* Then every entry in this Properties table is

* written out, one per line. For each entry the key string is

* written, then an ASCII =, then the associated

* element string. For the key, all space characters are

* written with a preceding \ character. For the

* element, leading space characters, but not embedded or trailing

* space characters, are written with a preceding \

* character. The key and element characters #,

* !, =, and : are written

* with a preceding backslash to ensure that they are properly loaded.

*

* After the entries have been written, the output stream is flushed.

* The output stream remains open after this method returns.

*

*

* @param writer an output character stream writer.

* @param comments a description of the property list.

* @exception IOException if writing this property list to the specified

* output stream throws an IOException.

* @exception ClassCastException if this Properties object

* contains any keys or values that are not Strings.

* @exception NullPointerException if writer is null.

* @since 1.6*/

public voidstore(Writer writer, String comments)

throws IOException

{

store0((writer instanceof BufferedWriter)?(BufferedWriter)writer

:newBufferedWriter(writer),

comments,false);

}/**

* Writes this property list (key and element pairs) in this

* Properties table to the output stream in a format suitable

* for loading into a Properties table using the

* {@link #load(InputStream) load(InputStream)} method.

*

* Properties from the defaults table of this Properties

* table (if any) are not written out by this method.

*

* This method outputs the comments, properties keys and values in

* the same format as specified in

* {@link #store(java.io.Writer, java.lang.String) store(Writer)},

* with the following differences:

*

*

The stream is written using the ISO 8859-1 character encoding.

*

*

Characters not in Latin-1 in the comments are written as

* \uxxxx for their appropriate unicode

* hexadecimal value xxxx.

*

*

Characters less than \u0020 and characters greater

* than \u007E in property keys or values are written

* as \uxxxx for the appropriate hexadecimal

* value xxxx.

*

*

* After the entries have been written, the output stream is flushed.

* The output stream remains open after this method returns.

*

* @param out an output stream.

* @param comments a description of the property list.

* @exception IOException if writing this property list to the specified

* output stream throws an IOException.

* @exception ClassCastException if this Properties object

* contains any keys or values that are not Strings.

* @exception NullPointerException if out is null.

* @since 1.2*/

public void store(OutputStream out, String comments)

throws IOException

{

store0(new BufferedWriter(new OutputStreamWriter(out, "8859_1")),

comments,true);

}

store(...)

storeToXML(OutputSteam, comment, encoding):写出到xml文件中。

/**

* Emits an XML document representing all of the properties contained

* in this table, using the specified encoding.

*

*

The XML document will have the following DOCTYPE declaration:

*


 

* <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

*

*

*

If the specified comment is null then no comment

* will be stored in the document.

*

*

The specified stream remains open after this method returns.

*

* @param os the output stream on which to emit the XML document.

* @param comment a description of the property list, or null

* if no comment is desired.

* @param encoding the name of a supported

*

* character encoding

*

* @throws IOException if writing to the specified output stream

* results in an IOException.

* @throws NullPointerException if os is null,

* or if encoding is null.

* @throws ClassCastException if this Properties object

* contains any keys or values that are not

* Strings.

* @see #loadFromXML(InputStream)

* @since 1.5*/

public voidstoreToXML(OutputStream os, String comment, String encoding)

throws IOException

{if (os == null)throw newNullPointerException();

XMLUtils.save(this, os, comment, encoding);

}

storeToXML(...)

四、源码分析

主要针对加载属性方法(load/loadFromXML)和写出属性到磁盘文件方法来进行分析(store/storeToXML)。

1、load(Reader)和load(InputStream)

这两个方法是指定从文本文件中加载key/value属性值,底层都是将流封装成为LineReader对象,然后通过load0方法来加载属性键值对的,加载完属性后流对象是不会关闭的。这两个方法对应的properties文件格式如下:

# this iscomment

key1:value1

key2=value2

key3 : vlaue3

key4 : value4

# the valueis 'value4', because the Properties only trim the space of the split charset before and after.

# key5=value5

#this iserror, the key not start with the space.

key6 value7

Properties Text File

LineReader源码分析:

classLineReader {/**

* 根据字节流创建LineReader对象

*

* @param inStream

* 属性键值对对应的字节流对象*/

publicLineReader(InputStream inStream) {this.inStream =inStream;

inByteBuf= new byte[8192];

}/**

* 根据字符流创建LineReader对象

*

* @param reader

* 属性键值对对应的字符流对象*/

publicLineReader(Reader reader) {this.reader =reader;

inCharBuf= new char[8192];

}//字节流缓冲区, 大小为8192个字节

byte[] inByteBuf;//字符流缓冲区,大小为8192个字符

char[] inCharBuf;//当前行信息的缓冲区,大小为1024个字符

char[] lineBuf = new char[1024];//读取一行数据时候的实际读取大小

int inLimit = 0;//读取的时候指向当前字符位置

int inOff = 0;//字节流对象

InputStream inStream;//字符流对象

Reader reader;/**

* 读取一行,将行信息保存到{@link lineBuf}对象中,并返回实际的字符个数

*

* @return 实际读取的字符个数

* @throws IOException*/

intreadLine() throws IOException {//总的字符长度

int len = 0;//当前字符

char c = 0;

boolean skipWhiteSpace= true;

boolean isCommentLine= false;

boolean isNewLine= true;

boolean appendedLineBegin= false;

boolean precedingBackslash= false;

boolean skipLF= false;while (true) {if (inOff >=inLimit) {//读取一行数据,并返回这一行的实际读取大小

inLimit = (inStream == null) ?reader.read(inCharBuf) : inStream.read(inByteBuf);

inOff= 0;//如果没有读取到数据,那么就直接结束读取操作

if (inLimit <= 0) {//如果当前长度为0或者是改行是注释,那么就返回-1。否则返回len的值。

if (len == 0 ||isCommentLine) {return -1;

}returnlen;

}

}//判断是根据字符流还是字节流读取当前字符

if (inStream != null) {//The line below is equivalent to calling a ISO8859-1 decoder.//字节流是根据ISO8859-1进行编码的,所以在这里进行解码操作。

c = (char) (0xff & inByteBuf[inOff++]);

}else{

c= inCharBuf[inOff++];

}//如果前一个字符是换行符号,那么判断当前字符是否也是换行符号

if(skipLF) {

skipLF= false;if (c == '\n') {continue;

}

}//如果前一个字符是空格,那么判断当前字符是不是空格类字符

if(skipWhiteSpace) {if (c == ' ' || c == '\t' || c == '\f') {continue;

}if (!appendedLineBegin && (c == '\r' || c == '\n')) {continue;

}

skipWhiteSpace= false;

appendedLineBegin= false;

}//如果当前新的一行,那么进入该if判断中

if(isNewLine) {

isNewLine= false;//如果当前字符是#或者是!,那么表示该行是一个注释行

if (c == '#' || c == '!') {

isCommentLine= true;continue;

}

}//根据当前字符是不是换行符号进行判断操作

if (c != '\n' && c != '\r') {//当前字符不是换行符号

lineBuf[len++] = c;//将当前字符写入到行信息缓冲区中,并将len自增加1.//如果len的长度大于行信息缓冲区的大小,那么对lineBuf进行扩容,扩容大小为原来的两倍,最大为Integer.MAX_VALUE

if (len ==lineBuf.length) {int newLength = lineBuf.length * 2;if (newLength < 0) {

newLength=Integer.MAX_VALUE;

}char[] buf = new char[newLength];

System.arraycopy(lineBuf,0, buf, 0, lineBuf.length);

lineBuf=buf;

}//是否是转义字符//flip the preceding backslash flag

if (c == '\\') {

precedingBackslash= !precedingBackslash;

}else{

precedingBackslash= false;

}

}else{//reached EOL

if (isCommentLine || len == 0) {//如果这一行是注释行,或者是当前长度为0,那么进行clean操作。

isCommentLine = false;

isNewLine= true;

skipWhiteSpace= true;

len= 0;continue;

}//如果已经没有数据了,就重新读取

if (inOff >=inLimit) {

inLimit= (inStream == null) ?reader.read(inCharBuf) : inStream.read(inByteBuf);

inOff= 0;if (inLimit <= 0) {returnlen;

}

}//查看是否是转义字符

if(precedingBackslash) {//如果是,那么表示是另起一行,进行属性的定义,len要自减少1.

len -= 1;//skip the leading whitespace characters in following line

skipWhiteSpace = true;

appendedLineBegin= true;

precedingBackslash= false;if (c == '\r') {

skipLF= true;

}

}else{returnlen;

}

}

}

}

}

根据这个源码,我们可以看出一些特征:readLine这个方法每次读取一行数据;如果我们想在多行写数据,那么可以使用'\'来进行转义,在该转义符号后面换行,是被允许的。

load0方法源码:

private voidload0(LineReader lr) throws IOException {char[] convtBuf = new char[1024];//读取的字符总数

intlimit;//当前key所在位置

intkeyLen;//value的起始位置

intvalueStart;//当前字符

charc;//

boolean hasSep;//是否是转义字符

boolean precedingBackslash;while ((limit = lr.readLine()) >= 0) {

c= 0;//key的长度

keyLen = 0;//value的起始位置默认为limit

valueStart =limit;//

hasSep = false;

precedingBackslash= false;//如果key的长度小于总的字符长度,那么就进入循环

while (keyLen

c =lr.lineBuf[keyLen];//如果当前字符是=或者是:,而且前一个字符不是转义字符,那么就表示key的描述已经结束

if ((c == '=' || c == ':') && !precedingBackslash) {//指定value的起始位置为当前keyLen的下一个位置

valueStart = keyLen + 1;//并且指定,去除空格

hasSep = true;break;

}else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) {//如果当前字符是空格类字符,而且前一个字符不是转义字符,那么表示key的描述已经结束//指定value的起始位置为当前位置的下一个位置

valueStart = keyLen + 1;break;

}//如果当前字符为'\',那么跟新是否是转义号。

if (c == '\\') {

precedingBackslash= !precedingBackslash;

}else{

precedingBackslash= false;

}

keyLen++;

}//如果value的起始位置小于总的字符长度,那么就进入该循环

while (valueStart

c =lr.lineBuf[valueStart];//判断当前字符是否是空格类字符,达到去空格的效果

if (c != ' ' && c != '\t' && c != '\f') {//当前字符不是空格类字符,而且当前字符为=或者是:,并在此之前没有出现过=或者:字符。//那么value的起始位置继续往后移动。

if (!hasSep && (c == '=' || c == ':')) {

hasSep= true;

}else{//当前字符不是=或者:,或者在此之前出现过=或者:字符。那么结束循环。

break;

}

}

valueStart++;

}//读取key

String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);//读取value

String value = loadConvert(lr.lineBuf, valueStart, limit -valueStart, convtBuf);//包括key/value

put(key, value);

}

}

我们可以看到,在这个过程中,会将分割符号两边的空格去掉,并且分割符号可以是=,:,空格等。而且=和:的级别比空格分隔符高,即当这两个都存在的情况下,是按照=/:分割的。可以看到在最后会调用一个loadConvert方法,该方法主要是做key/value的读取,并将十六进制的字符进行转换。

2、loadFromXML方法

该方法主要是提供一个从XML文件中读取key/value键值对的方法。底层是调用的XMLUtil的方法,加载完对象属性后,流会被显示的关闭。xml格式如下所示:

comments

value7

value7

value4

vlaue3

value2

value1

Properties XML File

底层调用的是XMLUtil.load方法,在该方法中是使用DOM方式来访问xml文件的,在这里不做详细的介绍。

3、store(InputStream/Reader,String)方法

该方法主要是将属性值写出到文本文件中,并写出一个comment的注释。底层调用的是store0方法。针对store(InputStream,String)方法,我们可以看到在调用store0方法的时候,进行字节流封装成字符流,并且指定字符集为8859-1。源码如下:

private voidstore0(BufferedWriter bw, String comments, boolean escUnicode) throws IOException {if (comments != null) {//写出注释, 如果是中文注释,那么转化成为8859-1的字符

writeComments(bw, comments);

}//写出时间注释

bw.write("#" + newDate().toString());//新起一行

bw.newLine();//进行线程间同步的并发控制

synchronized (this) {for (Enumeration e =keys(); e.hasMoreElements();) {

String key=(String) e.nextElement();

String val= (String) get(key);//针对空格进行转义,并根据是否需要进行8859-1编码

key = saveConvert(key, true, escUnicode);/** No need to escape embedded and trailing spaces for value,

* hence pass false to flag.*/

//value不对空格进行转义

val = saveConvert(val, false, escUnicode);//写出key/value键值对

bw.write(key + "=" +val);

bw.newLine();

}

}

bw.flush();

}

4、storeToXML方法

将属性写出到xml文件中,底层调用的是XMLUtil.store方法。不做详细的介绍。

五、实例

直接代码:

package com.gerry.bd.properties.jdk;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Properties;

import java.util.Set;/**

* 操作jdk自身操作属性配置文件的Properties类。

* jdk1.7文档地址:http://docs.oracle.com/javase/7/docs/api/

* java.util.Properties继承自HashTable,最主要的子类是Provider

*

* @author jsliuming

**/

public classPropertiesApp {public static voidmain(String[] args) {

InputStream input= null;//第一种,使用ClassLoad的方法获取InputStram对象。

input = PropertiesApp.class.getClassLoader().getResourceAsStream("propertiesApp.properties");//第二种,直接使用Class的方法来获取InputStream对象。必须加'/'表示在classpath路径下,如果不加的话,那么获取的是PropertiesApp这个类所在package下的文件。

input = PropertiesApp.class.getResourceAsStream("/propertiesApp.properties");

OutputStream os= null;try{

os= new FileOutputStream("storePropertiesApp.xml");

}catch(FileNotFoundException e1) {

}//第一步:创建Properties对象

Properties prop = newProperties();try{//第二步:加载属性, 不会自动关闭input输入流。

prop.load(input);//第三步:获取属性

String value1 = prop.getProperty("key1");

String value5= prop.getProperty("key5");

String value7= prop.getProperty("key7", "defaultvalue");

System.out.println("[key1:" + value1 + "],[key5:" + value5 + "],[key7:" + value7 + "]");

Set keys =prop.stringPropertyNames();

System.out.println("全部的key/value属性:");for(String key : keys) {

System.out.println("[" + key + "][" + prop.getProperty(key) + "]");

}//第四步:设置属性

prop.setProperty("key7", "value7");//第五步:保存成文件

prop.storeToXML(os, "comments");

}catch(IOException e) {

e.printStackTrace();

}finally{if(input != null) {try{

input.close();

}catch(IOException e) {//ignore

}

}if (os != null) {try{

os.close();

}catch(IOException e) {//ignore

}

}

}

}

}

PropertiesApp

结果console的输出为:

[key1:value1],[key5:null],[key7:defaultvalue]

全部的key/value属性:

[key6][value7]

[key4][value4 ]

[key3][vlaue3]

[key2][value2]

[key1][value1]

result

相关文章:

  • 几个事情随便说一下
  • java io 机器名_计算机等级二级Java考试辅导:Java IO机试题及解答(第2部分)
  • 申请了一个ASP免费的空间
  • inputdstream mysql_Spark Streaming编程模型
  • how to reinstall MS DTC on windows server 2003 R2
  • java linkedlist源码_深入分析java集合类LinkedList(源码分析)
  • 从诚恳出发,迈向自我实现
  • java 中的map_浅谈java中Map的用法
  • 学习SWT的一些资源
  • java http同步请求_java websocket 如何实现消息同步返回,类似 http 请求数据返回结果...
  • 一条路给出了道题:“还有一元钱去了哪里???”
  • java atm项目_java实现ATM取款项目
  • pyhon使用http代理服务器和POP3、SMTP邮件服务器
  • ubuntu server安装php mysql_Ubuntu杂记——Apache+PHP+MySQL的安装
  • 基于TCP/IP的手机聊天游戏(附带源码和解释)之共享类
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • JavaScript实现分页效果
  • java正则表式的使用
  • maya建模与骨骼动画快速实现人工鱼
  • PHP CLI应用的调试原理
  • Python 反序列化安全问题(二)
  • Rancher如何对接Ceph-RBD块存储
  • Twitter赢在开放,三年创造奇迹
  • uva 10370 Above Average
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 关于Flux,Vuex,Redux的思考
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 码农张的Bug人生 - 见面之礼
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 推荐一个React的管理后台框架
  • 微信开放平台全网发布【失败】的几点排查方法
  • Linux权限管理(week1_day5)--技术流ken
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #pragma预处理命令
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (floyd+补集) poj 3275
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (十八)SpringBoot之发送QQ邮件
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (一)UDP基本编程步骤
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .chm格式文件如何阅读
  • .net FrameWork简介,数组,枚举
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET项目中存在多个web.config文件时的加载顺序
  • //解决validator验证插件多个name相同只验证第一的问题
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka