首先加载Properties文件的方式有两种:
一种是通过spring框架加载:
我们通过源码来分析spring解析Properties文件是由PropertiesLoaderUtils类的fillProperties方法来解析的,源码如下
/**
* Actually load properties from the given EncodedResource into the given Properties instance.
* @param props the Properties instance to load into
* @param resource the resource to load from
* @param persister the PropertiesPersister to use
* @throws IOException in case of I/O errors
*/
static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister)
throws IOException {
InputStream stream = null;
Reader reader = null;
try {
String filename = resource.getResource().getFilename();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
stream = resource.getInputStream();
persister.loadFromXml(props, stream);
}
else if (resource.requiresReader()) {
reader = resource.getReader();
persister.load(props, reader); //关键方法
}
else {
stream = resource.getInputStream();
persister.load(props, stream); //关键方法
}
}
finally {
if (stream != null) {
stream.close();
}
if (reader != null) {
reader.close();
}
}
}
通过以上源码我们可以发现PropertiesLoaderUtils类调用了PropertiesPersister的load方法,源码如下
public class DefaultPropertiesPersister implements PropertiesPersister {
@Override
public void load(Properties props, InputStream is) throws IOException {
props.load(is);
}
@Override
public void load(Properties props, Reader reader) throws IOException {
props.load(reader);
}
......
}
而PropertiesPersister是通过Properties类来处理的,而Properties类则是java提供的,源码如下
public class Properties extends Hashtable {
public synchronized void load(InputStream inStream) throws IOException {
load0(new LineReader(inStream));
}
private void load0 (LineReader lr) throws IOException {
char[] convtBuf = new char[1024];
int limit;
int keyLen;
int valueStart;
char c;
boolean hasSep;
boolean precedingBackslash;
while ((limit = lr.readLine()) >= 0) { //读取一行信息
c = 0;
keyLen = 0;
valueStart = limit;
hasSep = false;
......
通过以上源码可以发现我们需要关注的地方是lr.readLine()用了读取一行信息,主要源码如下
if (c != '\n' && c != '\r') { //如果是"\n"或者"\r"则跳到else里面,else里是读取一行信息结束
lineBuf[len++] = c;
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) {
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) {
return len;
}
}
通过以上代码可以发现"\n"和"\r"都会认为是一行的结束。
结论“\r\n”和“\n”对spring方式读取Properties无影响
另一种是不通过spring方式读取
package com.hs.util;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Desc:properties文件获取工具类
*
*/
public class PropertyUtil {
private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);
private static Properties props;
static {
loadProps();
}
synchronized static private void loadProps() {
logger.info("开始加载properties文件内容.......");
props = new Properties();
InputStream in = null;
try {
in = PropertyUtil.class.getClassLoader()
.getResourceAsStream("server.properties");
props.load(in);
} catch (FileNotFoundException e) {
logger.error("properties文件未找到");
} catch (IOException e) {
logger.error("出现IOException");
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
logger.error("properties文件流关闭出现异常");
}
}
logger.info("加载properties文件内容完成...........");
logger.info("properties文件内容:" + props);
}
public static String getProperty(String key) {
if (null == props) {
loadProps();
}
return props.getProperty(key);
}
public static String getProperty(String key, String defaultValue) {
if (null == props) {
loadProps();
}
return props.getProperty(key, defaultValue);
}
}
通过以上代码可以发现,这种方式其实也是通过java提供的Properties类来加载的,所以“\r\n”和“\n”对读取Properties文件没有影响