day09 字节流 字符流 Properties
今日内容java
IO流
字节流 (输入流读, 输出流写) byte byte[]
字符流 (输入流读, 输出流写) char char[] String
异常处理 (通用格式, JDK7优化格式, JDK9优化格式)
Properties双列集合
存取数据
读写到文件
IO流
IO的概念和分类知识点:
什么是IO流
什么是输入
什么是输出
IO流有哪些分类
总结:java
IO流: 输入(Input)输出(Output)流
流: 数据流输入: 从硬盘(文件)读取到内存(Java程序)
输出: 从内存(Java程序)写入到硬盘(文件)
(入和出都是相对于内存来说的)
+---------+
输入 | | 输出
--------> | 内存 | -------->
| |
+---------+
IO流的分类:
字节流 (读写字节: byte, 可以读写所有类型的文件, 包括视频, 图片, 音频, 文本等)
字节输入流: java.io.InputStream 抽象类
字节输出流: java.io.OutputStream 抽象类
字符流 (读写字符: char, String, 只能读写文本文件)
字符输入流: java.io.Reader 抽象类
字符输出流: java.io.Writer 抽象类
| | 输入流 | 输出流 |
|-------|:---------|-----------|
| **字节流** | 字节输入流 InputStream | 字节输出流 OutputStream |
| **字符流** | 字符输入流 Reader | 字符输出流 Writer |补充:java 字节流
计算机中一切皆为字节知识点:
计算机中存储的数据是什么形式的
总结:java
计算机中, 无论文本, 视频, 音频, 图片... 一切都是以"字节byte"形式存储的
也就是以数字形式存储的, 而数字可以用不同进制表示, 计算机能看懂的是二进制数字
补充:java 字节输出流: OutputStream和FileOutputStream知识点:
OutputStream抽象类 有哪些共性方法
FileOutputStream普通类 可以做什么
创建FileOutputStream对象, 会有哪3个作用
![](./img/IO流体系.PNG)总结:java
java.io.OutputStream抽象类: 字节输出流 (顶层类)
// 成员方法
void close() :释放资源
void flush() :刷新缓冲区(对于字节流来说没有作用)
// 写字节的成员方法
abstract void write(int b): 一次写一个字节 (参数int便于传递byte的整数不用强转)
void write(byte[] b): 一次写一个字节数组
void write(byte[] b, int offset, int len): 一次写一个字节数组的一部分
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
// 构造方法
FileOutputStream(String name): 通过文件路径创建文件字节输出流
FileOutputStream(File file): 通过File对象创建文件字节输出流
构造方法的作用:
1. 创建一个FileOutputStream对象
2. 根据构造方法传递的路径, 在磁盘上创建一个空文件 ("如果文件存在则会清空数据")
3. 将创建的FileOutputStream对象指向这个磁盘上的文件
补充:java 字节输出流: 一次写一个字节到文件知识点:
了解Java程序将数据写入文件的原理
FileOutputStream写数据到文件需要哪3步
总结:java
写数据的原理:
Java程序 -> JVM虚拟机 -> OS操作系统 -> OS调用写数据的方法 -> 将数据写入文件
使用字节输出流写数据到文件的步骤:
1. 创建对象: 创建FileOutputStream对象, 构造方法中传递文件路径
2. 写入数据: 使用FileOutputStream对象调用 write(int b) 方法, 将字节写入文件
3. 释放资源: 使用FileOutputStream对象调用 close() 方法, 关闭流对象释放资源
FileOutputStream fos = new FileOutputStream("模块名\\文件名.txt");
fos.write(97);
fos.close();
补充:java 5分钟练习: 使用FileOutputStream写数据到文件java
需求:
创建FileOutputStream对象, 路径传递当前模块下的testOutputStream1.txt文件 "day09\\testOutputStream1.txt"
write() 写入 97, 98, 99
close() 释放资源
打开文件查看
代码:java
public class Test {
public static void main(String[] args) throws IOException { // 为了学习IO流时不让try catch打乱代码结构, 我们先throws声明抛出
// 1. 创建文件字节输出流对象
FileOutputStream fos = new FileOutputStream("day09\\testOutputStream1.txt");
// 2. 写数据
fos.write(97);
fos.write(98);
fos.write(99);
// 3. 释放资源
fos.close();
}
}
文件存储原理和记事本打开文件的原理知识点:
向文件中写入字节数据时, 写入的是什么进制的数据
写入文件的是数字, 但文本编辑器打开后为什么会显示为字符
总结:java
向文件中写入字节数据时, 十进制的数字会被转换为"二进制"的数字写入文件文本编辑器打开文本文件时, 会先查询编码表, 将二进制数字转换为对应的字符进行显示
0-127: 查询ASCII码表 -128~127
其他: 查询系统默认码表
Windows简体中文系统的程序打开是按 GBK 码表
IDEA中使用的是 UTF-8 码表 ASCII编码表: 1个byte就是一个字符 97 a
GBK编码表: 2个byte数字组成一个汉字. "你": -60, -29
UTF-8编码表: 3个byte数字组成一个汉字. "你": -28, -67, -96
补充:java 字节输出流: 一次写多个字节知识点:java
如何一次性写入多个byte
如何获取一个字符串对应的byteString -> byte
"abc" -> byte byte byte补充:
java.lang.String类:
byte[] getBytes(): 使用平台的默认字符集将此String编码为byte数组
总结:java
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
void write(byte[] b): 一次写一个字节数组
void write(byte[] b, int off, int len): 一次写一个字节数组的一部分
Java中, byte的范围是 -128 ~ 127 共256个数值
编码表中字符范围是 0 ~ 255 共256个数值
写多个字节时:
如果第一个字节是正数中的 0~127, 则记事本会查询 ASCII码表 显示字符
如果第一个字节是负数中的:-128~-1, 则记事本会查询 GBK码表 显示字符.(将两个连续的byte组合为一个中文)
补充:java
FileOutputStream fos = new FileOutputStream(new File("09_IOAndProperties\\b.txt"));
byte[] bytes2 = "你好".getBytes();
System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67]
fos.write(bytes2);//释放资源
fos.close();
字节输出流: 续写, 换行知识点:
如何在文件已有内容之后, 接着写入内容 (续写)
如何在文件中写入换行, Windows系统的换行符号是什么
总结:java
java.io.FileOutputStream类: 文件字节输出流
// 带有 续写 功能的构造方法, 不会清空文件
FileOutputStream(String name, boolean append): 通过文件路径创建流, true可以续写
FileOutputStream(File file, boolean append): 通过File对象创建流, true可以续写
换行符:
Windows系统: "\r\n"
Linux系统: "\n"
MacOS系统: "\r"
补充:java 5分钟练习: 续写和换行java
需求:
创建FileOutputStream对象, 指向当前模块下的testOutputStream2.txt文件, 并开启续写
for循环5次, 每次循环写入"你好"的byte数组, 并写入windows的换行符的byte数组
循环结束后释放资源
运行程序查看效果, 再次运行再次查看效果
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 创建文件字节输出流对象
FileOutputStream fos = new FileOutputStream("day09\\testOutputStream2.txt", true); // 追加写 // 循环写入5行数据
for (int i = 0; i < 5; i++) {
// 写入文字
fos.write("你好".getBytes());
// 在文字后写入换行符
fos.write("\r\n".getBytes());
} // 释放资源
fos.close();
}
}
字节输入流: InputStream和FileInputStream知识点:
InputStream抽象类 有哪些共性的方法
FileInputStream普通类 可以做什么
![](./img/IO流体系.PNG)总结:java
java.io.InputStream抽象类: 字节输入流 (顶层类)
// 常用成员方法
void close(): 释放资源
// 读数据的方法
int read(): 一次读一个字节
读到文件末尾返回-1 (返回int也是为了代码编写方便)
int read(byte[] b): 一次读一个字节数组
读到的字节存放在参数中的字节数组中, 返回int值是本次读到的字节的个数. 读到文件末尾返回-1
java.io.FileInputStream类: 文件字节输入流
// 构造方法
FileInputStream(String name): 使用文件路径创建文件字节输入流
FileInputStream(File file): 使用File对象创建文件字节输入流
构造方法的作用:
1. 创建FileInputStream对象
2. 将FileInputStream对象指向磁盘上的文件
补充:java 字节输入流: 一次读取一个字节知识点:
了解Java程序从文件读取数据的原理
FileInputStream读数据需要哪3步
总结:java
Java程序从文件读取数据的原理:
Java程序 -> JVM虚拟机 -> OS(操作系统) -> OS调用读取的方法 -> 读取磁盘文件数据
java.io.InputStream抽象类: 字节输入流 (顶层类)
int read(): 一次读一个字节
读到文件末尾返回-1 (返回int也是为了代码编写方便)
FileInputStream读数据步骤:
1. 创建FileInputStream对象
2. 使用FileInputStream对象, 调用 int read() 方法, 一次读取一个byte
3. 释放资源
FileInputStream fis = new FileInputStream("模块名\\文件名");
// 一次读一个字节:
int by; // int变量用来存储每次读到的数据
while ( ( by = fis.read() ) != -1 ) {
System.out.print((char)by); // 不要换行, 文件中自带换行的byte
} fis.close();
补充:java 5分钟练习: 一次读取一个字节java
需求:
在当前模块中, 手动创建一个文件testInputStream1.txt, 双击打开直接在里面写入abc三个字母.
使用FileInputStream读取该文件, 一次读取一个byte, 每次将读到的byte强转为char后, 打印到控制台
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 1. 创建文件字节输入流对象
FileInputStream fis = new FileInputStream("day09\\testInputStream1.txt"); // 2. 读取文件: 一次读取一个字节
int by; // 定义一个变量, 用于存储每次读到的字节
while ((by = fis.read()) != -1) { // 循环读取, 如果不是-1, 则说明读到了数据, 在循环体中操作; 如果是-1, 则循环结束
// 将读取到的字节从int类型强转为char, 便于我们看懂字符, 打印出来
System.out.println((char)by);
} // 3. 释放资源
fis.close();
}
}
字节输入流: 一次读取一个字节原理知识点:
字节输入流一次读取一个字节是如何实现的
总结:java
![](./img/03_字节流一次读取一个字节原理.bmp)补充:java 字节输入流: 一次一个字节数组知识点:java
如何一次读取多个byte
一次读取多个byte是如何实现的, 相比于一次读取一个byte效率上哪个更高补充:
java.lang.String类:
String(byte[] bytes): 使用平台默认字符集解码将byte数组转换为String
String(byte[] bytes, int offset, int length): 使用平台默认字符集将数组一部分转换为String
总结:java
java.io.InputStream抽象类: 字节输入流 (顶层类)
int read(byte[] b): 一次读一个字节数组
参数 byte[] b 作用: 存储每次读到的字节, 起到缓冲作用
返回值作用: 每次读到的字节个数, 读到文件末尾返回-1
// 示例代码
FileInputStream fis = new FileInputStream("模块名\\文件名");byte[] bytes = new byte[1024]; // 定义字节数组, 用于保存每次读取到的数据
int len; // 定义int变量, 用于保存每次读取到的长度
while ((len = fis.read(bytes)) != -1) {
String s = new String(bytes, 0, len); // 将读取到的字节转换为字符串, 读到多少个就转换多少个
System.out.print(s);
}fis.close(); // 释放资源
![](./img/03_字节流一次读取多个字节原理.bmp)补充:java 5分钟练习: 一次读取一个字节数组java
需求:
在当前模块中, 手动创建一个文件testInputStream2.txt, 双击打开直接在里面写入ABCDE五个字母.
使用FileInputStream读取该文件, 使用一次读写一个字节数组的方式, 每次读到的数组转换为String, 打印到控制台
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 创建文件字节输入流对象
FileInputStream fis = new FileInputStream("day09\\testInputStream2.txt"); // 读取文件: 一次读取一个字节数组
byte[] bytes = new byte[1024]; // 创建数组用于保存读到的字节数据
int len; // 定义int变量用于保存每次读到的字节个数
while ((len = fis.read(bytes)) != -1) {
// 读到的数据都在bytes数组中, 读到多少个, 转换多少个, 不要全转
String s = new String(bytes, 0, len); // 从0索引转换len个字节为String
System.out.println(s);
}
// 释放资源
fis.close();
}
}
字节流复制图片文件知识点:
如何通过 FileInputStream 和 FileOutputStream 实现文件复制
总结:java
文件复制的步骤:
1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
3.使用字节输入流对象中的方法read读取文件
4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
5.释放资源
// 创建输入流和输出流
FileInputStream fis = new FileInputStream("c:\\1.jpg"); //输入流指向要读的数据源文件
FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); //输出流指向要写的目的地文件
// 一次读写一个字节数组
byte[] bytes = new byte[1024];
int len = 0;
while((len = fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
// 释放资源
fos.close();
fis.close();
![](./img/04_文件复制的原理.bmp)补充:java 5分钟练习: 字节流复制图片
需求:
将D盘中的"小岳岳.jpg"图片, 使用一次读写一个字节数组的方式, 复制到当前模块目录下, 名为"小岳岳复制.jpg"
代码:java
public class Test {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis(); // 创建文件字节输入流对象 (读取 数据源)
FileInputStream fis = new FileInputStream("d:\\小岳岳.jpg");
// 创建文件字节输出流对象 (写入 目的地)
FileOutputStream fos = new FileOutputStream("day09\\小岳岳复制.jpg"); // 复制文件方式1: 一次读写一个字节
/*
int by;
while ((by = fis.read()) != -1) {
// 读到一个写一个
fos.write(by);
}
*/ // 复制文件方式2: 一次读写一个字节数组
int len;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
// 读到多少写多少, 不要全写
fos.write(bytes, 0, len);
} // 释放资源
fos.close();
fis.close(); long end = System.currentTimeMillis();
System.out.println("复制耗时:" + (end - start) + "毫秒");
// 一次读写一个字节 复制耗时:1309毫秒
// 一次读写一个字节数组 复制耗时:35毫秒
}
}
字节流读取中文问题知识点:
字节流读取中文是否方便?
GBK编码中, 一个汉字占用几个byte
UTF-8编码中, 一个汉字占用几个byte
总结:java
GBK编码中, 一个汉字占用2个byte
UTF-8编码中, 一个汉字占用3个byte
补充:java 字符流
字符输入流: Reader和FileReader知识点:
Reader类有哪些共性方法
FileReader类可以做什么
![](./img/IO流体系.PNG)总结:java
注意: 字符流只能读写"文本文件"java.io.Reader抽象类: 字符输入流 (顶层)
// 常用成员方法
void close() :关闭此流并释放与此流相关联的任何系统资源
// 读
int read(): 一次读一个字符char, 返回读到的字符.
读到文件末尾返回-1 (返回int为了代码编写方便)
int read(char[] cbuf): 一次读取一个字符数组char[]
返回读取的字符个数. 读到文件末尾返回-1
java.io.FileReader类: 文件字符输入流
// 构造方法
FileReader(File file): 根据File对象创建文件字符输入流
FileReader(String fileName): 根据File对象创建文件字符输入流
构造方法的作用:
1. 创建FileReader对象
2. 将FileReader对象指向磁盘上的文件
补充:java 字符输入流: 2种方式读取文本文件知识点:
如何使用 FileReader 的 一次读一个字符 的方式, 实现读取文件
如何使用 FileReader 的 一次读一个字符数组 的方式, 实现读取文件
总结:java
java.io.Reader抽象类: 字符输入流 (顶层)
int read(): 一次读一个字符char, 返回读到的字符.
读到文件末尾返回-1 (返回int为了代码编写方便)
int read(char[] cbuf): 一次读取一个字符数组char[]
返回读取的字符个数. 读到文件末尾返回-1
java.lang.String类:
String(char[] value): 将char数组转换为String
String(char[] value, int offset, int count): 将char数组的一部分转换为String
FileReader fr = new FileReader("a.txt");// 一次读一个字符
int ch; // 定义变量保存每次读到的字符
while ((ch = fr.read()) != -1) {
System.out.print((char)ch);
}// 一次读一个字符数组
char[] cs = new char[1024];
int len;
while ((len = fr.read(cs)) != -1) {
String s = new String(cs, 0, len);
System.out.print(s);
}// 释放资源
fr.close();
5分钟练习: 字符流读取文件
需求:
使用FileReader的 一次读写一个字符, 和 一次读写一个字符数组 2种方式, 读取当前模块下的随便某一个文本文件, 打印到控制台
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 创建文件字符输入流对象
FileReader fr = new FileReader("day09\\Test.java"); // 读取文件方式1: 一次读取一个字符
/*
int ch; // 定义一个变量, 保存每次读到的字符
while ((ch = fr.read()) != -1) {
// 将读取到的int值强转为char类型
System.out.print((char)ch); // 打印不换行, 因为读取到的字符中有换行符
}
*/ // 读取文件方式2: 一次读取一个字符数组
int len;
char[] chs = new char[1024];
while ((len = fr.read(chs)) != -1) {
// 先将读到的字符数组转换为String
String s = new String(chs, 0, len);
System.out.print(s); // 打印不换行, 因为读取到的字符中有换行符
} // 释放资源
fr.close();
}
}
字符输出流: Writer和FileWriter知识点:
Writer类有哪些共性方法
FileWriter类可以做什么
创建FileWriter对象时有哪3个作用
![](./img/IO流体系.PNG)总结:java
java.io.Writer抽象类: 字符输出流 (顶层类) 'a''b' 缓冲区 97 98
// 常用成员方法
abstract void close(): 刷新缓冲区并释放资源
abstract void flush() :刷新缓冲区
// 写
void write(int c): 写一个字符 (int类型为了代码编写方便)
void write(char[] cbuf): 写一个字符数组
abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
void write(String str): 写一个字符串
void write(String str, int off, int len): 写一个字符串的一部分
注意: write()方法只是将数据写到内存缓冲区, 最后必须调用flush()或close()才能将数据真正写入磁盘java.io.FileWriter类: 文件字符输出流
// 构造方法
FileWriter(File file): 通过File对象创建文件字符输出流
FileWriter(String fileName): 通过文件路径创建文件字符输出流
作用:
1. 创建FileWriter对象
2. 根据构造方法中的路径, 在磁盘上创建文件 ("如果文件已存在, 则清空文件内容")
3. 将FileWriter对象指向磁盘上的文件
字符输出流: 一次写一个字符知识点:
如何使用 FileWriter 一次写一个字符 到文件
总结:java
void write(int c): 写一个字符 (int类型为了代码编写方便)FileWriter使用步骤:
1.创建FileWriter对象, 构造方法中绑定要写入数据的目的地
2.使用FileWriter中的方法 write(), 把数据写入到"内存缓冲区"中(字符转换为字节的过程)
3.使用FileWriter中的方法 flush(), 把内存缓冲区中的数据,"刷新到文件中"
4.释放资源 close() (会先把内存缓冲区中的数据刷新到文件中)
FileWriter fw = new FileWriter("09_IOAndProperties\\d.txt");
fw.write(97); // int ch 用int值代表char
//fw.flush();
fw.close();
补充:java 字符输出流: flush与close区别知识点:java
flush() 和 close() 方法有什么区别
close() 关流后, 能否继续读写数据
flush() 和 close() 方法哪个可以省略
总结:java
区别:
flush(): 刷新缓冲区 (将数据从内存中写入到磁盘)
close(): 刷新缓冲区, 并释放资源. 关闭流后不能再用同一个流对象操作flush() 可以省略, 只用 close()来 刷新并释放资源
补充:java 字符输出流: 其他方法知识点:
其他write()方法可以写入什么样的数据
总结:java
写的其他方法:
void write(char[] cbuf): 写一个字符数组
abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
void write(String str): 写一个字符串
void write(String str, int off, int len): 写一个字符串的一部分
补充:java 5分钟练习: FileWriter其他方法java
需求:
向当前模块中的testFileWriter.txt文件中, 分别使用以下方式写入数据:
写一个字符方式, 写入 '0'
写一个字符数组方式, 写入 {'a', 'b', 'c', 'd', 'e'}
写一个字符数组的一部分方式, 写入上面数组的前3个字符
写一个字符串的方式, 写入"传智播客"
写一个字符串的一部分的方式, 写入"黑马程序员"的后3个字符串
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 创建字符文件输出流对象
FileWriter fw = new FileWriter("day09\\testFileWriter.txt"); // 写一个字符方式, 写入 '0'
fw.write('0'); // 参数是int类型, 将char类型值赋值给int类型, 自动类型转换, 是可以的
// 写一个字符数组方式, 写入 {'a', 'b', 'c', 'd', 'e'}
char[] chs = {'a', 'b', 'c', 'd', 'e'};
fw.write(chs);
// 写一个字符数组的一部分方式, 写入上面数组的前3个字符
fw.write(chs, 0, 3);
// 写一个字符串的方式, 写入"传智播客"
fw.write("传智播客");
// 写一个字符串的一部分的方式, 写入"黑马程序员"的后3个字符串
fw.write("黑马程序员", 2, 3); // 释放资源
fw.close();
}
}
字符输出流: 续写, 换行知识点:
FileWriter如何续写和换行
总结:java
FileWriter中带有续写功能的构造:
FileWriter(File file, boolean append): 通过File对象创建流. 第二个参数为true可以续写
FileWriter(String fileName, boolean append): 通过文件路径创建流. 第二个参数为true可以续写
换行:
windows: "\r\n" fw.write("\r\n");
补充:java
字节流 和 字符流 如何选择:
1. 如果不确定读写的是什么类型的数据, 用字节流最通用
2. 如果确定读写的就是文本, 用字符流最方便
IO异常处理
IO流操作中的异常处理知识点:
IO流使用try catch的标准格式是什么
总结:java
IO流的标准格式: FileWriter fw = null;
try {
//IO流对象的创建, 操作等代码
fw = new FileWriter("d:\\09_IOAndProperties\\g.txt", true);
for (int i = 0; i <10 ; i++) {
fw.write("HelloWorld"+i+"\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
补充:java JDK7和JDK9中IO异常处理的不同方式知识点:
JDK 7 和 JDK 9 对于IO流的异常处理, 分别做了哪些简化, 格式分别是什么
总结:java
JDK 7 增加的 "try-with-resource"
省略了 finally, 可自动释放资源
// 格式
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
// 示例
try (FileWriter fw = new FileWriter("fw.txt");FileReader fr = new FileReader("fr.txt")) {
// IO操作
int ch = fr.read();
fw.write(ch);
} catch (IOException e) {
e.printStackTrace();
}
JDK 9 对于"try-with-resource"的改进:
流对象的声明和创建可以放在括号外面
流对象要求是有效final的.(即不要修改流对象的值) FileWriter fw = new FileWriter("fw.txt");
FileReader fr = new FileReader("fr.txt");
try (fw; fr) {
// IO操作
int ch = fr.read();
fw.write(ch);
} catch (IOException e) {
e.printStackTrace();
}
补充:java
// JDK 9 的格式适用于定义方法时, 通过参数传递流对象
public static void method(FileWriter fw, FileReader fr) {
try (fw; fr) {
// IO操作
int ch = fr.read();
fw.write(ch);
} catch (IOException e) {
e.printStackTrace();
}
}
Properties集合
Properties存储数据和遍历知识点:
Properties双列集合存储的键和值是什么数据类型
Properties双列集合有哪些特有方法
总结:java
Properties双列集合:
键和值都是 String 类型java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
// 构造方法
Properties(): 创建一个Properties集合
// 可以使用Map接口中的方法
// 特有成员方法
Object setProperty(String key, String value): 保存/替换键值对
String getProperty(String key): 通过键获取值. 键不存在返回null
Set<String> stringPropertyNames(): 返回键的集合
void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文),并写入注释
void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能中文)
void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以中文)
补充:java Properties: store()存储数据到文件知识点:
如何将Properties中存储的键值对, 写入到文件
总结:java
Properties将数据写入到文件的方法:
void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文), 并写入注释
使用步骤:
1.创建Properties集合对象,添加数据
2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
4.释放资源
补充:java
属性集(配置文件), 标准的后缀是 .properties
配置文件格式要求:
一行一个键值对
键和值中间用=分隔 (标准格式, 但空格分开也行)
表示单行注释
示例: `db.properties`properties
This is a comment!
className=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456
5分钟练习: 使用Properties添加数据并写入文件java
需求:
使用Properties集合, 添加以下键值对:
"赵丽颖", "168"
"迪丽热巴", "165"
"古力娜扎", "160"
使用 store(Writer writer, String comments) 方法将数据写入到当前模块下的prop.properties文件中
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 先创建Properties集合对象
Properties properties = new Properties(); // 向集合中添加键值对数据
properties.setProperty("赵丽颖", "168");
properties.setProperty("迪丽热巴", "165");
properties.setProperty("古力娜扎", "160"); // 数据目前在集合中, 也就是在内存中
// 要想持久化存储, 则需要调用store方法来存储
FileWriter fw = new FileWriter("day09\\prop.properties");
properties.store(fw, "save data"); // 释放流的资源
fw.close();
}
}
Properties: load()从文件加载数据到集合知识点:
如何将磁盘上的配置文件加载到Properties集合
总结:java
Properties将数据从文件加载到集合中的方法:
void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
使用步骤:
1.创建Properties集合对象
2.使用Properties集合对象中的方法load读取保存键值对的文件
3.遍历Properties集合
补充:java 5分钟练习: 加载文件数据到Propertiesjava
需求:
从刚才的prop.properties文件中, 使用 load(Reader reader) 方法加载数据到Properties集合, 使用Set<String> stringPropertyNames() 方法遍历打印到控制台
代码:java
public class Test {
public static void main(String[] args) throws IOException {
// 创建Properties集合对象
Properties properties = new Properties();
// 目前新创建的集合对象中什么数据都没有
// 需要调用load方法从磁盘上加载数据
properties.load(new FileReader("day09\\prop.properties")); // 调用完方法后, 集合中就已经有键值对了, 先获取所有键的集合, 然后遍历
Set<String> set = properties.stringPropertyNames();
for (String key : set) {
// 通过键获取值
String value = properties.getProperty(key);
System.out.println(key + "=" + value);
}
}
}
--- 今日APIjava
IO流:
java.io.OutputStream抽象类: 字节输出流 (顶层类)
// 成员方法
void close() :释放资源
void flush() :刷新缓冲区(对于字节流来说没有作用)
// 写字节的成员方法
abstract void write(int b): 一次写一个字节 (参数是int是为了代码中写表示byte的整数方便不用强转)
void write(byte[] b): 一次写一个字节数组
void write(byte[] b, int off, int len): 一次写一个字节数组的一部分
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
// 构造方法
FileOutputStream(String name): 通过文件路径创建文件字节输出流
FileOutputStream(File file): 通过File对象创建文件字节输出流
FileOutputStream(String name, boolean append): 通过文件路径创建文件字节输出流, true可以续写
FileOutputStream(File file, boolean append): 通过File对象创建文件字节输出流, true可以续写
java.io.InputStream抽象类: 字节输入流 (顶层类)
// 常用成员方法
void close(): 释放资源
// 读数据的方法
int read(): 一次读一个字节. 读到文件末尾返回-1 (返回int也是为了代码编写方便)
int read(byte[] b): 一次读一个字节数组. 读到的字节存放在参数中的字节数组中, 返回int值是本次读到的字节的个数. 读到文件末尾返回-1
java.io.FileInputStream类: 文件字节输入流
// 构造方法
FileInputStream(String name): 使用文件路径创建文件字节输入流
FileInputStream(File file): 使用File对象创建文件字节输入流
java.io.Reader抽象类: 字符输入流 (顶层)
// 常用成员方法
void close() :关闭此流并释放与此流相关联的任何系统资源
// 读数据的方法
int read(): 一次读一个字符char, 返回读到的字符. 读到文件末尾返回-1 (返回int为了代码编写方便)
int read(char[] cbuf): 一次读取一个字符数组char[]. 返回读取的字符个数. 读到文件末尾返回-1
java.io.FileReader类: 文件字符输入流
// 构造方法
FileReader(File file): 根据File对象创建文件字符输入流
FileReader(String fileName): 根据File对象创建文件字符输入流
java.io.Writer抽象类: 字符输出流 (顶层类)
// 常用成员方法
abstract void close(): 刷新缓冲区并释放资源
abstract void flush() :刷新缓冲区
// 写
void write(int c): 写一个字符 (int类型为了代码编写方便)
void write(char[] cbuf): 写一个字符数组
abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
void write(String str): 写一个字符串
void write(String str, int off, int len): 写一个字符串的一部分
java.io.FileWriter类: 文件字符输出流
// 构造方法
FileWriter(File file): 通过File对象创建文件字符输出流
FileWriter(String fileName): 通过文件路径创建文件字符输出流
FileWriter(File file, boolean append): 通过File对象创建文件字符输出流. 第二个参数为true可以续写
FileWriter(String fileName, boolean append): 通过文件路径创建文件字符输出流. 第二个参数为true可以续写
集合:
java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
// 构造方法
Properties(): 创建一个Properties集合
// 可以使用Map接口中的方法
// 特有成员方法
Object setProperty(String key, String value): 保存/替换键值对
String getProperty(String key): 通过键获取值. 键不存在返回null
Set<String> stringPropertyNames(): 返回键的集合
void store(OutputStream out, String comments): 将集合数据用字节流写入文件(不能中文), 并写入注释
void store(Writer writer, String comments): 将集合数据用字符流写入文件(可以中文), 并写入注释
void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
IO流截止今日的IO流体系结构
字节流
|_ InputStream 字节输入流顶层
|_ FileInputStream 文件字节输入流
|_ OutputStream 字节输出流顶层
|_ FileOutputStream 文件字节输出流
字符流
|_ Reader 字符输入流顶层
|_ FileReader 文件字符输入流
|_ Writer 字符输出流顶层
|_ FileWriter 文件字符输出流
![](./img/IO流体系.PNG) 今日目标 能够说出IO流的分类和功能java
按操作的数据分:
字节流: 操作 byte byte[]
字符流: 操作 char char[] String
按方向分:
输入流: 读
输出流: 写
能够使用字节输出流写出数据到文件java
字节输出流: OutputStream FileOutputStream1. 创建流对象
2. 调用write()写数据: 一个字节, 一个字节数组
3. 释放资源 close()
能够使用字节输入流读取数据到程序java
字节输入流: InputStream FileInputStream1. 创建流对象
2. 调用
int read(): 一次读一个字节
int read(byte[] bytes): 一次读一个字节数组
3. 释放资源
能够理解读取数据read(byte[])方法的原理java
byte[] bytes = new byte[2]; 文件中有ABCDEint len;
len = fis.read(bytes); // [A, B] 2
len = fis.read(bytes); // [C, D] 2
len = fis.read(bytes); // [E, D] 1
能够使用字节流完成文件的复制java
1. 创建输入输出流对象
2. 循环读写
一次读写一个字节
一次读写一个字节数组
3. 释放资源
能够使用FileWriter写数据到文件java
1. 创建流对象
2. 调用write()写数据
3. 释放资源
能够说出FileWriter中关闭和刷新方法的区别java
关闭: close()
close先刷新缓冲区, 然后释放资源
close之后不能写数据
刷新: flush()
flush只能刷新缓冲区
flush之后能写数据
能够使用FileWriter写数据的5个方法java
write(int ch): 一次写一个字符
write(char[] chs): 一次写一个字符数组
write(char[] chs, int offset, int len): 一次写一个字符数组的一部分
write(String s): 一次写一个字符串
write(String s, int offset, int len): 一次写一个字符串的一部分
能够使用FileWriter写数据实现换行和追加写java
换行:
windows: "\r\n"
linux: "\n"
mac: "\r"
追加写:
2个参数的构造
FileWriter(String filename, boolean append) true追加
能够使用FileReader读数据java
1. 创建流对象
2. 调用
int read(): 一次读一个字符
int read(char[] chs): 一次读一个字符数组
3. 释放资源
能够使用FileReader读数据一次一个字符数组java
int len;
char[] chs = new char[1024];
while ((len = fr.read(chs)) != -1) {
}
能够使用Properties的load方法加载文件中配置信息java
1. 创建Properties集合对象
2. 调用load(流对象)
3. 遍历集合
|
|