java IO教程《四》
properties使用
什么是Properties?
Properties(Java.util.Properties),该类主要用于读取Java的配置文件,不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的。
Properties 详解
properties结构
Api介绍
构造函数
| 构造函数 | 说明 |
|---|---|
| Properties() | 创建空的Properties |
| Properties(Properties ps) | 基于已经存在的properties去创建 |
常用方法
| 方法 | 说明 |
|---|---|
| public synchronized void load(InputStream inStream) | 给予输入流去加载Properties |
| public synchronized void load(Reader reader) | 给予文本输入流去加载Properties |
| Object setProperty(String key, String value) | 设置属性 |
| public synchronized void load(InputStream inStream) | 给予输入流去加载Properties |
| public void store(Writer writer, String comments) | 保存文件 |
| public String getProperty(String key) | 获取properties key |
源码讲解
load源码分析
指定从流中加载key/value属性值,底层都是将流封装成为LineReader对象,然后通过load0方法来加载属性键值对的,加载完属性后流对象是不会关闭的。这两个方法对应的properties文件格式如下:
class LineReader {
/**
* 根据字节流创建LineReader对象
*
* @param inStream
* 属性键值对对应的字节流对象
*/
public LineReader(InputStream inStream) {
this.inStream = inStream;
inByteBuf = new byte[8192];
}
/**
* 根据字符流创建LineReader对象
*
* @param reader
* 属性键值对对应的字符流对象
*/
public LineReader(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
*/
int readLine() 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;
}
return len;
}
}
// 判断是根据字符流还是字节流读取当前字符
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) {
return len;
}
}
// 查看是否是转义字符
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 {
return len;
}
}
}
}
}
store源码分析
private void store0(BufferedWriter bw, String comments, boolean escUnicode) throws IOException {
2 if (comments != null) {
3 // 写出注释, 如果是中文注释,那么转化成为8859-1的字符
4 writeComments(bw, comments);
5 }
6 // 写出时间注释
7 bw.write("#" + new Date().toString());
8 // 新起一行
9 bw.newLine();
10 // 进行线程间同步的并发控制
11 synchronized (this) {
12 for (Enumeration e = keys(); e.hasMoreElements();) {
13 String key = (String) e.nextElement();
14 String val = (String) get(key);
15 // 针对空格进行转义,并根据是否需要进行8859-1编码
16 key = saveConvert(key, true, escUnicode);
17 /*
18 * No need to escape embedded and trailing spaces for value,
19 * hence pass false to flag.
20 */
21 // value不对空格进行转义
22 val = saveConvert(val, false, escUnicode);
23 // 写出key/value键值对
24 bw.write(key + "=" + val);
25 bw.newLine();
26 }
27 }
28 bw.flush();
29 }
properties实战
实现读取ex1.properties文件写入另外一个文件ex2.properties
- 准备文件test.properties
#bbaba
#Mon Jun 07 11:38:21 CST 2021
hah=ceshi
- 开始拷贝
Properties properties = new Properties();
properties.load(new FileReader(new File("test.properties")));
System.out.println(properties.get("hah"));
properties.store(new FileWriter(new File("test2.properties")),"ceshi2");
- 控制台输出
ceshi
Process finished with exit code 0
此时classpath下可以查看到新建的test2.properties文件。
结束
识别下方二维码!回复:
入群,扫码加入我们交流群!
点赞是认可,在看是支持
java IO教程《四》的更多相关文章
- Java IO教程
1 Java IO 教程 2 Java IO 概述 3 Java IO: 文件 4 Java IO: 管道 5 Java IO: 网络 6 Java IO: 字节和字符数组 7 Java IO: S ...
- Java IO(四) InputStream 和 OutputStream
Java IO(四) InputStream 和 OutputStream 一.介绍 InputStream 和 OutputStream 是字节流的超类(父类),都是抽象类,都是通过实例化它们的子类 ...
- Java IO学习--(四)网络
Java中网络的内容或多或少的超出了Java IO的范畴.关于Java网络更多的是在我的Java网络教程中探讨.但是既然网络是一个常见的数据来源以及数据流目的地,并且因为你使用Java IO的API通 ...
- Java IO(四)——字符流
一.字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为一个Unicode字符占用2 ...
- Java IO教程 导读
Java IO是一套java 用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并有输入产生一些输出.Java为此提供了java.io包. 如果你浏览下java.io包,会对其中各样的类 ...
- Java IO(四)
在文件操作流中,输入输出的目标都是文件,但是有时候,我们并不需要写入文件,只是需要中转一下而已,这样就会显得很麻烦,所以我们就可以使用内存操作流.在内存操作流中,输入输出目标都是内存. 内存输出流:B ...
- 系统学习 Java IO (十四)----字符读写缓存和回退 BufferedReader/BufferedWriter & PushbackReader
目录:系统学习 Java IO---- 目录,概览 BufferedReader BufferedReader 类构造器接收一个 Reader 对象,为 Reader 实例提供缓冲. 缓冲可以加快 I ...
- java IO教程《三》
缓冲区流讲解(Buffered) 什么是缓冲区? 缓冲流,也叫高效流,是对4个基本的File流的增强,所以也是4个流,按照数据类型分类: 字节缓冲流:BufferedInputStream,Buffe ...
- Java入门教程四(字符串处理)
Java 语言的文本数据被保存为字符或字符串类型.字符及字符串的操作主要用到 String 类和 StringBuffer 类,如连接.修改.替换.比较和查找等. 定义字符串 直接定义字符串 直接定义 ...
随机推荐
- 908. Smallest Range I
Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K, and ...
- 【Scrapy(二)】Scrapy 中的 Pipline,Item,Shell组件
Pipline: 1.爬虫项目与爬虫的区别与关联: 一个爬虫项目可以包含多个爬虫,如下图中爬虫项目firstspider 包含多个爬虫itcst 和爬虫itcast1 2.多个爬虫是公用一套Pipli ...
- hdu2067 简单dp或者记忆化搜索
题意: 小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- ubuntu14.04忽然不能登录,输入密码一直返回登录界面
解决方法: 1.ctrl + alt + F1进入命令终端 2.重装gdm,sudo apt-get install gdm 3.修改启动顺序:dpkg -reconfigure gdm 4.重启re ...
- hdu4768 非常规的二分
题意: n个社团给同学发传单,同学一共有1--2^31这么多,每个社团有三个数A ,B ,C ,只有 满足 A ,A + C ,A + C + C ...A + KC <= B 的学 ...
- POJ1236 强连通 (缩点后度数的应用)
题意: 一些学校有一个发送消息的体系,现在给你一些可以直接发送消息的一些关系(单向)然后有两个问题 (1) 问你至少向多少个学校发送消息可以让所有的学校都得到消息 (2) 问至少加多少条边 ...
- 逆向与分析-WebBrowserPassView消息分析
逆向与分析-WebBrowserPassView消息分析 这个的源头是之前我写的一个博客: http://blog.csdn.net/u013761036/article/details/730427 ...
- JetBrains系列软件用法
IDEA JSON格式化 IDEA的JSON_Formatter插件,下载地址 安装方式:File->Settings->Plugins,然后选择INstall plugin from d ...
- 全套Project版本安装教程及下载地址
1:Project 2007 安装教程及下载地址 https://mp.weixin.qq.com/s/8iI7x1qjon0yAdo3bStjzw 2:Project 2010 安装教程及下载地址 ...
- MFC对话框不能使用菜单更新宏ON_UPDATE_COMMAND_UI
菜单更新宏的原理 更新处理宏的工作原理是基于框架窗口类的.MFC中对话框菜单更新宏的原理是:当我们使用从CFrameWnd框架窗口类中派生的类创建窗口时,当我们单击菜单且菜单还未弹出前会产生WM_IN ...
