IO流学习笔记二
缓冲流
缓冲流概述
缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流
。
作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
。
问题1:缓冲流的作用?
缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。
问题2:缓冲流有几种?
字节缓冲流
字节缓冲输入流:BufferedInputStream
字节缓冲输出流:BufferedOutputStream
字符缓冲流
字符缓冲输入流:BufferedReader
字符缓冲输出流:BufferedWriter
字节缓冲流
字节缓冲流性能优化原理:
字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,与硬盘的交互次数减少,所以性能较好
。
字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了
。
字节缓冲流
字节缓冲输入流BufferedInputStream
:提高字节输入流读取数据
的性能,读写功能上并无变化。
字节缓冲输出流BufferedOutputStream
:提高字节输出流读取数据
的性能,读写功能上并无变化。
构造器 | 说明 |
---|---|
public BufferedInputStream(InputStream is) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
public BufferedOutputStream(OutputStream os) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
代码测试案例:
import java.io.*;
public class ByteBufferDemo {
public static void main(String[] args) throws Exception{
try(
// 这里面只能放置资源对象,用完会自动关闭;自动调用资源对象的close方法关闭资源
// 1. 创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream("C:\\Users\\lenovo\\Desktop\\1.mp4");
// a. 把原始的字节输入流包装成高级的缓冲字节输入流
// BufferedInputStream bis = new BufferedInputStream(is);
InputStream bis = new BufferedInputStream(is); // 两种写法都可以,为多态的写法;
// 2. 创建一个字节输出流管道与目的连接
OutputStream os = new FileOutputStream("C:\\Users\\lenovo\\Desktop\\2.mp4");
// b. 把原始字节输出流包装成高级的缓冲字节输出流
// BufferedOutputStream bos = new BufferedOutputStream(os);
OutputStream bos = new BufferedOutputStream(os); // 多态的写法
){
// 3. 定义一个字节数组转移数据
long start = System.currentTimeMillis();
int len;
while ((len = is.read()) != -1){
os.write(len);
}
long end = System.currentTimeMillis();
System.out.println("拷贝视频所需时间为:" + (end - start)/1000 + "s");
}catch (IOException e){
e.printStackTrace();
}
}
}
问题1:字节缓冲流为什么提高了操作数据的性能?
字节缓冲流自带8KB缓冲区
可以提高原始字节流、字符流读写数据的性能
问题2:字节缓冲流的功能如何调用?
public BufferedOutputStream(OutputStream os)
public BufferedInputStream(InputStream is)
功能上并无很大变化,性能提升了。
字节缓冲流的性能分析
为了测试字节缓冲流的性能,我们分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时。
1、使用低级的字节流按照一个一个字节的形式复制文件。
2、使用低级的字节流按照一个一个字节数组的形式复制文件。
3、使用高级的缓冲字节流按照一个一个字节的形式复制文件。
4、使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。
代码测试案例:
import java.io.*;
/**
目标:利用字节流的复制统计各种写法形式下缓冲流的性能执行情况。
复制流:
(1)使用低级的字节流按照一个一个字节的形式复制文件。
(2)使用低级的字节流按照一个一个字节数组的形式复制文件。
(3)使用高级的缓冲字节流按照一个一个字节的形式复制文件。
(4)使用高级的缓冲字节流按照一个一个字节数组的形式复制文件。
小结:
使用高级的缓冲字节流按照一个一个字节数组的形式复制文件,性能好,建议开发使用!
*/
public class ByteBufferTimeDemo {
public static final String SRC_FILE = "C:\\Users\\lenovo\\Desktop\\1.mp4";
private static final String DEST_FILE = "C:\\Users\\lenovo\\Desktop\\";
public static void main(String[] args) {
// copy01(); // 使用低级的字节流按照一个一个字节的形式复制文件:慢的让人简直无法忍受。直接被淘汰。
// copy02(); // 使用低级的字节流按照一个一个字节数组的形式复制文件: 比较慢,但是还是可以忍受的!
// copy03(); // 缓冲流一个一个字节复制:很慢,不建议使用。
copy04(); // 缓冲流一个一个字节数组复制: 平常拷贝文件就是用这一个
}
private static void copy04() {
System.out.println("缓冲流一个一个字节数组复制~~~");
try(
// 1. 创建一个输入流管道
InputStream is = new FileInputStream(SRC_FILE);
// a. 创建高级输入缓冲流
InputStream bis = new BufferedInputStream(is); // 多态的写法
// 2. 创建一个输出流管道
OutputStream os = new FileOutputStream(DEST_FILE + "4.mp4");
// b. 创建高级输出缓冲流
OutputStream bos = new BufferedOutputStream(os);
){
long start = System.currentTimeMillis();
int len;
byte[] buffer = new byte[1024];
while ((len = bis.read()) != -1){
bos.write(buffer, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节数组复制: " + (end - start)/1000.0 + "s");
}catch (Exception e){
e.printStackTrace();
}
}
private static void copy03() {
System.out.println("缓冲流一个一个字节复制~~~");
try(
// 1. 创建一个输入流管道
InputStream is = new FileInputStream(SRC_FILE);
// a. 创建高级输入缓冲流
InputStream bis = new BufferedInputStream(is); // 多态的写法
// 2. 创建一个输出流管道
OutputStream os = new FileOutputStream(DEST_FILE + "3.mp4");
// b. 创建高级输出缓冲流
OutputStream bos = new BufferedOutputStream(os);
){
long start = System.currentTimeMillis();
int len;
while ((len = bis.read()) != -1){
bos.write(len);
}
long end = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节复制: " + (end - start)/1000.0 + "s");
}catch (Exception e){
e.printStackTrace();
}
}
private static void copy02() {
System.out.println("使用低级的字节流按照一个一个字节数组的形式复制文件~~~");
try(
// 1. 创建一个输入流管道
InputStream is = new FileInputStream(SRC_FILE);
// 2. 创建一个输出流管道
OutputStream os = new FileOutputStream(DEST_FILE + "2.mp4")
){
long start = System.currentTimeMillis();
int len;
byte[] buffer = new byte[1024];
while ((len = is.read()) != -1){
os.write(buffer, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("使用低级的字节流按照一个一个字节数组的形式复制文件: " + (end - start)/1000.0 + "s");
}catch (Exception e){
e.printStackTrace();
}
}
private static void copy01() {
System.out.println("使用低级的字节流按照一个一个字节的形式复制文件~~~");
try(
// 1. 创建一个输入流管道
InputStream is = new FileInputStream(SRC_FILE);
// 2. 创建一个输出流管道
OutputStream os = new FileOutputStream(DEST_FILE + "1.pdf")
){
long start = System.currentTimeMillis();
int len;
while ((len = is.read()) != -1){
os.write(len);
}
long end = System.currentTimeMillis();
System.out.println("使用低级的字节流按照一个一个字节的形式复制文件: " + (end - start)/1000.0 + "s");
}catch (Exception e){
e.printStackTrace();
}
}
}
字符缓冲流
字符缓冲输入流
字符缓冲输入流BufferedReader作用
:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。
构造器 | 说明 |
---|---|
public BufferedReader(Reader r) | 可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,从而提高字符输入流读数据的性能 |
字符缓冲输入流新增功能:
方法 | 说明 |
---|---|
public String readLine() | 读取一行数据返回,如果读取没有完毕,无行可读返回null |
BufferedReader代码测试案例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class BufferedReaderDemo {
public static void main(String[] args) {
try(
// 1. 创建一个文件字符输入流与源文件接通
Reader fr = new FileReader("Day11/src/text.txt");
// 2. 把低级的字符输入流包装成高级的缓冲字符输入流。
BufferedReader bfr = new BufferedReader(fr);
){
// 1、一次读取单个字符
// System.out.println((char)bfr.read());
// 2、一次性读取一个数组的数据
// char[] buffer = new char[1024]; // 这里对应的是字符输入流而不是字节,所以定义为char类型的数组而不是byte类型的数组
// int len;
// while ((len = bfr.read(buffer)) != -1){
// String str = new String(buffer, 0, len);
// System.out.println(str);
// }
// 3、每次读取一行数据
String str;
// 特别注意,readLine为BufferedReader的特有方法,在上面实例化对象bfr的时候
// 就不能使用多态的形式了,如果继续使用多态,就只能使用Reader中定义的方法,不能使用BufferedReader独有的方法,这个要特别注意
while ((str = bfr.readLine()) != null){
System.out.println(str);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
字符缓冲输出流
字符缓冲输出流BufferedWriter作用
:提高字符输出流写取数据的性能,除此之外多了换行功能
构造器 | 说明 |
---|---|
public BufferedWriter(Writer w) | 可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能 |
字符缓冲输出流新增功能:
方法 | 说明 |
---|---|
public void newLine() | 换行操作 |
BufferedWriter代码测试案例:
import java.io.*;
public class BufferedWriterDemo {
public static void main(String[] args) {
try(
// 1、创建字符输出流管道与目标文件联通
Writer wr = new FileWriter("Day11/src/1.txt", true); // 可以追加数据
// 2、把低级字符输出流封装成高级字符输出流
BufferedWriter bwr = new BufferedWriter(wr);
){
// 写一个字符进去
bwr.write(97);
bwr.write('a');
bwr.write("卢");
bwr.newLine(); // 自动换算
// 写一个字符串进去
bwr.write("sdkjfklsjdfkljs;adf就看电视剧付款了撒看拉萨的减肥决胜巅峰来看");
bwr.newLine();
// 写一个字符数组进去
char[] chars = "jfklasjdfkljasdklf接口的撒九分裤".toCharArray();
bwr.write(chars);
bwr.newLine();
// 写一个字符串的一段进去
bwr.write("担惊受恐垃圾啊弗兰克阿所经历的咖啡机", 0, 5);
bwr.newLine();
}catch (IOException e){
e.printStackTrace();
}
}
}
问题1:字符缓冲流为什么提高了操作数据的性能?
字符缓冲流自带8K缓冲区
可以提高原始字符流读写数据的性能
问题2:字符缓冲流的功能如何使用?
public BufferedReader(Reader r)
性能提升了,多了readLine()按照行读取的功能
public BufferedWriter(Writer w)
性能提升了,多了newLine()换行的功能
测试案例:拷贝出师表到另一个文件,恢复顺序
需求:把《出师表》的文章顺序进行恢复到一个新文件中。
分析:
1、定义一个缓存字符输入流管道与源文件接通。
2、定义一个List集合存储读取的每行数据。
3、定义一个循环按照行读取数据,存入到List集合中去。
4、对List集合中的每行数据按照首字符编号升序排序。
5、定义一个缓存字符输出管道与目标文件接通。
6、遍历List集合中的每个元素,用缓冲输出管道写出并换行。
出师表内容格式:
代码实现:
import java.io.*;
import java.util.*;
public class BufferedCharTest {
public static void main(String[] args) {
try(
// 1. 定义字符输入流
Reader fr = new FileReader("Day11/src/csb.txt");
// a. 把低级的字符输入流封装为高级的字符输入流
BufferedReader bfr = new BufferedReader(fr);
// 2. 定义字符输出流
Writer wr = new FileWriter("Day11/src/csbNew.txt");
// b. 把低级的字符输出流封装成高级的字符输出流
BufferedWriter bwr = new BufferedWriter(wr);
){
// 3. 一行一行读取文件中的数据加入到LinkedList集合中去
List<String> list = new ArrayList<>();
String str;
while ((str = bfr.readLine()) != null){
list.add(str); // 添加到集合中
}
// 4. 排序
// 要是自定义类的话就要换成其他的方法了,实现Compareble接口中的compareTo方法,或者new Compareble()匿名内部类
// 自定义比较器
List<Integer> listSort = new ArrayList<>();
Collections.addAll(listSort, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,14, 15);
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return listSort.indexOf(Integer.parseInt(o1.substring(0, o1.indexOf('.')))) -
listSort.indexOf(Integer.parseInt(o2.substring(0, o2.indexOf('.'))));
}
});
// 5. 遍历结合吸入文件中
for(String strTemp : list){
bwr.write(strTemp);
bwr.newLine(); // 换行
}
}catch (IOException e){
e.printStackTrace();
}
}
}
实验截图:
转换流
问题引出:不同编码读取乱码问题
1、之前我们使用字符流读取中文是否有乱码?
没有的,因为代码编码和文件编码都是UTF-8。
2、如果代码编码和文件编码不一致,使用字符流直接读取还能不乱码吗?
会乱码。
文件编码和读取的编码必须一致才不会乱码。
测试案例:使用相同编码读取不同编码的文件内容:
需求:分别使用如下两种方式读取文件内容
代码编码是UTF-8,文件编码也是UTF-8,使用字符流读取观察输出的中文字符结果。
代码编码是UTF-8,文件编码使用GBK,使用字符流读取观察输出的中文字符结果
字符流直接读取文本内容注意事项:
必须文件和代码编码一致才不会乱码
如果文件和代码编码不一致,读取将出现乱码。
字符输入转换流
字符输入转换流
字符输出转换流
字符输入转换流InputStreamReader
:可以把原始的字节流按照指定编码转换成字符输入流。
构造器 | 说明 |
---|---|
public InputStreamReader(InputStream is) | 可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader一样。 |
public InputStreamReader(InputStream is ,String charset) | 可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点) |
测试代码:
问题1:字符输入转换流InputStreamReader作用?
可以解决字符流读取不同编码乱码的问题
public InputStreamReader(InputStream is,String charset):
可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。
字符输出转换流
字符输出转换流
字符输入转换流OutputStreamWriter
:可以把字节输出流按照指定编码转换成字符输出流。
构造器 | 说明 |
---|---|
public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。 |
public OutputStreamWriter(OutputStream os,String charset) | 可以把原始的字节输出流按照指定编码转换成字符输出流(重点) |
测试代码:
问题1:字符输出转换流OutputStreamWriter的作用?
public OutputStreamWriter(OutputStream os,String charset)
可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!
序列化对象
对象序列化
对象序列化作用
:以内存为基准,把内存中的对象存储到磁盘文件中去
,称为对象序列化。
使用到的流是对象字节输出流:ObjectOutputStream
对象序列化使用到的流是对象字节输出流:ObjectOutputStream
构造器 | 说明 |
---|---|
public ObjectOutputStream(OutputStream out) | 把低级字节输出流包装成高级的对象字节输出流 |
ObjectOutputStream序列化方法
方法名称 | 说明 |
---|---|
public final void writeObject(Object obj) | 把对象写出去到对象序列化流的文件中去 |
代码测试案例:
Student类:
ObjectOutputStreamDemo类型:
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
1、transient修饰的成员变量不参与序列化了
2、对象如果要序列化,必须实现Serializable序列化接口。
3、申明序列化的版本号码,序列化的版本号与反序列化的版本号必须一致才不会出错!
private static final long serialVersionUID = 1;
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws Exception{
// 1. 创建学生对象
Student s = new Student("赵六", "zhaoliu", "12345618", 18);
// 2. 对象序列化:使用对象字节输出流包装字节输出流管道
OutputStream os = new FileOutputStream("Day11/src/123.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
// 3. 直接调用序列化方法
oos.writeObject(s);
// 4. 释放资源
oos.close();
}
}
查看文件123.txt
问题1:对象序列化的含义是什么?
把对象数据存入到文件中去。
问题2:对象序列化用到了哪个流?
对象字节输出流ObjectOutputStram
public void writeObject(Object obj)
问题3:序列化对象的要求是怎么样的?
对象必须实现序列化接口
注意事项:
1、transient修饰的成员变量不参与序列化了,这样是为了保护隐私信息,例如age,password等字段
2、对象如果要序列化,必须实现Serializable序列化接口。
3、申明序列化的版本号码,序列化的版本号与反序列化的版本号必须一致才不会出错!
private static final long serialVersionUID = 1;
对象反序列化
对象反序列化:
使用到的流是对象字节输入流ObjectInputStream
:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象
,称为对象反序列化。
对象反序列化使用到的流是对象字节输入流:ObjectInputStream
构造器 | 说明 |
---|---|
public ObjectInputStream(InputStream out) | 把低级字节输如流包装成高级的对象字节输入流 |
ObjectInputStream序列化方法
方法名称 | 说明 |
---|---|
public Object readObject() | 把存储到磁盘文件中去的对象数据恢复成内存中的对象返回 |
代码测试案例:
问题1:对象反序列化的含义是什么?
把磁盘中的对象数据恢复到内存的Java对象中。
问题2:对象反序列化用到了哪个流?
对象字节输入流ObjectInputStram
public Object readObject()
打印流
PrintStream、PrintWriter
打印流
作用
:打印流可以实现方便、高效的打印数据到文件中去。
打印流一般是指:PrintStream,PrintWriter两个类
。
可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。
PrintStream
构造器 | 说明 |
---|---|
public PrintStream(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintStream(File f) | 打印流直接通向文件对象 |
public PrintStream(String filepath) | 打印流直接通向文件路径 |
PrintWriter
构造器 | 说明 |
---|---|
public PrintWriter(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintWriter (Writer w) | 打印流直接通向字符输出流管道 |
public PrintWriter (File f) | 打印流直接通向文件对象 |
public PrintWriter (String filepath) | 打印流直接通向文件路径 |
PrintStream和PrintWriter的区别
打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势),
高效的原因在于PrintStream内部封装了BufferedOutputStream, PrintWriter内部封装了BufferedWriter;
PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
PrintWriter继承自字符输出流Writer,支持写字符数据出去。
测试代码实现:
import java.io.*;
public class PrintDemo {
public static void main(String[] args) throws Exception{
// 1. 创建一个打印流对象
PrintStream psm = new PrintStream("Day11/src/psm.txt");
PrintStream psm1 = new PrintStream(new FileOutputStream("Day11/src/psm1.txt", true)); // 追加数据,在低级管道后面加True
PrintStream psm2 = new PrintStream(new File("Day11/src/psm2.txt"));
// 2. 打印东西
psm.println(97);
psm.println(true);
psm.println(23.2);
psm.println("我是打印流~~~~"); // 打印直接存入文件当中
psm.write(97); // 写入a
psm1.println(97);
psm1.println(true);
psm1.println(23.2);
psm1.println("我是打印流~~~~");
psm2.println(97);
psm2.println(true);
psm2.println(23.2);
psm2.println("我是打印流~~~~");
psm.close();
psm1.close();
psm2.close();
System.out.println("---------------------------------------------------");
PrintWriter pwr = new PrintWriter("Day11/src/pwr.txt");
PrintWriter pwr1 = new PrintWriter(new FileOutputStream("Day11/src/pwr1.txt", true));
PrintWriter pwr2 = new PrintWriter(new File("Day11/src/pwr2.txt"));
pwr.println(97);
pwr.println(true);
pwr.println(23.2);
pwr.println("我是打印流~~~~");
pwr1.println(97);
pwr1.println(true);
pwr1.println(23.2);
pwr1.println("我是打印流~~~~");
pwr2.println(97);
pwr2.println(true);
pwr2.println(23.2);
pwr2.println("我是打印流~~~~");
pwr.close(); // 有时候文件中没有内容要使用os.flush()或者os.close()进行刷新缓冲流
pwr2.close();
pwr1.close();
}
}
输出语句的重定向
输出语句重定向:属于打印流的一种应用,可以把输出语句的打印位置改到文件
。
PrintStream ps = new PrintStream("文件地址");
System.setOut(ps);
代码测试案例:
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class PrintDemo1 {
public static void main(String[] args) throws FileNotFoundException {
// 源码
// 在System定义静态变量out: public final static PrintStream out = null;
// 可以看到out是PrintStream打印流的实例化对象
System.out.println("锦瑟无端五十弦");
System.out.println("一弦一柱思华年");
// 改变输出语句的位置(重定向),这样可以把打印在控制台的内容打印到一个指定的文件中去。
PrintStream ps = new PrintStream("Day11//src/log.txt");
System.setOut(ps); // 把系统打印流改成我们自己的打印流
System.out.println("庄生晓梦迷蝴蝶");
System.out.println("望帝春心托杜鹃");
}
}
Properties
Properties属性集对象
其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用
。
Properties核心作用:
Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
Properties的API && Properties和IO流结合的方法:
构造器 | 说明 |
---|---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
public Object setProperty(String key, String value) | 保存键值对(put) |
public String getProperty(String key) | 使用此属性列表中指定的键搜索属性值 (get) |
public Set stringPropertyNames() | 所有键的名称的集合 (keySet()) |
store测试案例:
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo1 {
public static void main(String[] args) throws IOException {
// 1. 需求: 使用Properties把键值对信息存入到属性文件中去
Properties properties = new Properties(); // Properties extends Hashtable<Object,Object> implements Map<K,V>,
/**
* public synchronized Object setProperty(String key, String value) {
* return put(key, value);
* }
* 可以发现setProperty底层源码还是put函数,相当于对put函数进行了一层封装,这种思想要学会。
*/
properties.setProperty("admin", "1213456");
properties.setProperty("lushm", "09346e");
properties.setProperty("heima", "itcast");
System.out.println(properties);
// 2. 加载属性文件中的键值对数据到属性对象properties中去
// 参数1:保存管道,字符输出流管道
// 参数2:个人新的,随便写
properties.store(new FileWriter("Day11/src/login.properties"), "第一次使用Properties保存信息~~~");
}
}
load测试案例:
import java.io.FileReader;
import java.io.Reader;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo2 {
public static void main(String[] args) throws Exception{
Properties properties = new Properties();
System.out.println(properties); // {}
// 加载属性文件中的键值对数据到属性对象properties中去
properties.load(new FileReader("Day11/src/login.properties"));
System.out.println(properties); // {admin=1213456, lushm=09346e, heima=itcast}
Set<String> set = properties.stringPropertyNames();
for(String key : set){
System.out.println(key + "----------" + properties.getProperty(key)); //getProperty的底层原理实际上为get,Object oval = super.get(key);
}
}
}
问题1:Properties的作用?
可以存储Properties属性集的键值对数据到属性文件中去:
void store(Writer writer, String comments)
可以加载属性文件中的数据到Properties对象中来:
void load(Reader reader)
IO框架
commons-io概述
1、commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
2、commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils
FileUtils主要有如下方法:
构造器 | 说明 |
---|---|
String readFileToString(File file, String encoding) | 读取文件中的数据, 返回字符串 |
void copyFile(File srcFile, File destFile) | 复制文件。 |
void copyDirectoryToDirectory(File srcDir, File destDir | 复制文件夹。 |
测试代码案例:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.*;
/**
目标:Commons-io包的使用介绍。
什么是Commons-io包?
commons-io是apache开源基金组织提供的一组有关IO操作的类库,
可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类,
见下表:
| 包 | 功能描述 |
| ----------------------------------- | :------------------------------------------- |
| org.apache.commons.io | 有关Streams、Readers、Writers、Files的工具类 |
| org.apache.commons.io.input | 输入流相关的实现类,包含Reader和InputStream |
| org.apache.commons.io.output | 输出流相关的实现类,包含Writer和OutputStream |
| org.apache.commons.io.serialization | 序列化相关的类
步骤:
1. 下载commons-io相关jar包;链接:https://pan.baidu.com/s/1DNKxkyd2F9JQViMMJtZPiQ 提取码:sf5g
2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
3. 将commons-io-2.6.jar加入到classpath中
小结:
IOUtils和FileUtils可以方便的复制文件和文件夹!!
*/
public class CommonsIODemo {
public static void main(String[] args) throws Exception{
// // 1.完成文件复制!
IOUtils.copy(new FileInputStream("E:\\resource\\图片1.jpg"),
new FileOutputStream("E:\\resource\\图片11.jpg"));
// 2.完成文件复制到某个文件夹下!
FileUtils.copyFileToDirectory(new File("E:\\resource\\图片1.jpg"), new File("E:\\"));
// 3.完成文件夹复制到某个文件夹下!
FileUtils.copyDirectoryToDirectory(new File("E:\\resource"),
new File("E:\\aaa"));
FileUtils.deleteDirectory(new File("E:\\aaa")); // 删除文件夹,即使不是空的文件,慎用,不经过回收站
}
}