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 类,如连接.修改.替换.比较和查找等. 定义字符串 直接定义字符串 直接定义 ...
随机推荐
- SQL 查询的执行顺序
SELECT语句的完整语法如下 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN & ...
- 用vue-cli3搭建vue项目
1.在nodejs官网下载node安装包,并进行安装:http://nodejs.cn/download/,在环境变量进行配置,并添加node_global和node_cache路径. 2.在D盘新建 ...
- DVWA之Insecure Captcha
Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...
- Python脚本扫描给定网段的MAC地址表(scapy或 python-nmap)
目录 用scapy模块写 用 python-nmap 模块写 python3.7 windows环境 以下两个都可以扫描指定主机或者指定网段的 IP 对应的 MAC 地址,然后保存到 csv 文件中 ...
- Windows核心编程笔记之错误处理
0x01 GetLastError() 函数用于获取上一个操作的错误代码 #include <Windows.h> #include <iostream> using name ...
- (邹博ML)凸优化
目录 凸集的基本概念 凸函数的基本概念 凸优化的一般提法 凸集基本概念 思考两个不能式 两个正数的算术平均数大于等于几何平均数 给定可逆对称阵Q,对于任意向量x,y,有: 思考凸集和凸函数 在机器学习 ...
- sharding JDBC 不支持批量导入解决方法
package com.ydmes.service.impl.log; import com.ydmes.domain.entity.log.BarTraceBackLog;import org.sp ...
- 腾讯暑期 前后七面 + hr(已拿offer面经)
以下是时间线 魔方 魔术师工作室 3.19 一面(120mins) c++ struct和union区别? 指针和引用的区别? 左值和右值? 字节对齐的作用? 什么情况下需要自定义new? mallo ...
- C++ primer plus读书笔记——第14章 C++中的代码重用
第14章 C++中的代码重用 1. 使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现).获得接口是is-a关系的组成部分.而使用组合,类可以获得实现,但不能获得接口. ...
- CRM是什么意思,有哪些作用?
我们总会听到一些人提到CRM或CRM系统,但是通常不知道它的含义,所以今天小Z就来详细介绍一下CRM. GartnerGroup1993年首次提出了这一概念:所谓的客户关系管理就是为企业提供一个全面的 ...