Day10、缓冲流-打印流
![image-20220513093850515]()
缓冲流
缓冲流概述
-
缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
-
作用: 缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
![image-20220513094457288]()
![image-20220513094522739]()
字节缓冲流性能优化原理:
-
字节缓冲输入流自带了8KB 缓冲池, 以后我们直接从缓冲池读取数据, 所以性能较好。
-
字节缓冲输出流自带了8KB 缓冲池, 数据就直接写入到缓冲池中去, 写数据性能极高了。
构造器 |
说明 |
public BufferedInputStream(lnputStream is) |
可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道, 从而提高字节输入流读数据的性能 |
public BufferedOutputStream(OutputStream OS) |
可以把低级的字节输出流包装成一个高级的缓冲字节输出流/ 从而提高写数据的性能 |
InputStream is = new FileInputStream(new File("src\\data3.txt"));
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(new File("src\\data4.txt"));
BufferedOutputStream bos = new BufferedOutputStream(os);
测试:分别使用不同的方式复制大视频观察性能情况
![image-20220513100625364]()
public class ByteBufferDemo02 {
public static final String SRC_FILE = "E:\\BaiduNetdiskDownload\\C Primer Plus公开课视频和代码\\" +
"C Primer Plus教学录屏\\C_Primer_Plus_5.7.mp4";
public static final String DEST_FILE = "E:\\CopyTest\\";
public static void main(String[] args) {
copy02();
copy04();
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try {
InputStream is = new FileInputStream(SRC_FILE);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "video4.avi");
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(len);
}
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节数组复制流耗费时间:" + (endTime - startTime) / 1000.0 + 's');
}
private static void copy03() {
long startTime = System.currentTimeMillis();
try {
InputStream is = new FileInputStream(SRC_FILE);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILE + "video3.avi");
BufferedOutputStream bos = new BufferedOutputStream(os);
int b;
while ((b = bis.read()) != -1){
bos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节流复制耗费时间:" + (endTime - startTime) / 1000.0 + 's');
}
private static void copy02() {
long startTime = System.currentTimeMillis();
try {
FileInputStream is = new FileInputStream(SRC_FILE);
FileOutputStream os = new FileOutputStream(DEST_FILE + "video2.avi");
byte[] buffer = new byte[1024 * 8];
int len;
while ((len = is.read(buffer)) != -1){
os.write(len);
}
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节一个一个字节数组流耗费时间:" + (endTime - startTime) / 1000.0 + 's');
}
private static void copy01() {
long startTime = System.currentTimeMillis();
try {
FileInputStream is = new FileInputStream(SRC_FILE);
FileOutputStream os = new FileOutputStream(DEST_FILE + "video1.avi");
int b;
while ((b = is.read()) != -1){
os.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节流一个一个耗费时间:" + (endTime - startTime) / 1000.0 + 's');
}
}
字符缓冲输入流
-
字符缓冲输入流: BufferedReader
-
作用: 提高字符输入流读取数据的性能, 除此之外多了按照行读取数据的功能。
构造器 |
说明 |
public BufferedReader(Reader r) |
可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道, 从而提高字符输入流读数据的性能 |
字符串缓冲输入流新增功能
方法 |
说明 |
public String readLine() |
读取一行数据返回, 如果读取没有完毕, 无行可读返回null |
FileReader fr = new FileReader("src\\data3.txt");
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
字符缓冲输出流
-
字符缓冲输出流: BufferedWriter
-
作用: 提高字符输出流写取数据的性能, 除此之外多了换行功能
构造器 |
说明 |
public BufferedWriter(Writer w) |
可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道, 从而提高字符输出流写数据的性能 |
方法 |
说明 |
public void newLine() |
换行操作 |
总结:
1 · 字符缓冲流为什么提高了操作数据的性能?
-
字符缓冲流自带8K 缓冲区
-
可以提高原始字符流读写数据的性能
2 · 字符缓冲流的功能如何使用?
-
public BufferedReader(Reader r)
-
性能提升了, 多了readLine() 按照行读取的功能
-
public BufferedWriter(Writer w)
-
性能提升了, 多了newLine() 换行的功能
案例:拷贝出师表恢复顺序
![image-20220513110603205]()
转换流

总结:
字符流直接读取文本内容:1.必须文件和代码编码一致才不会乱码
2.如果文件和代码编码不一致, 读取将出现乱码。


字符输入转换流
构造器 |
说明 |
public InputStreamReader(InputStream is) |
可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用, 与默认的FiIeReader— 样。 |
public InputStreamReader(InputStream is,String charset) |
可以把原始的字节流按照指定编码转换成字符输入流/ 这样字符流中的字符就不乱码了( 重点) |

字符输出转换流
-
字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。
构造器 |
说明 |
public OutputStreamWriter(OutputStream OS) |
可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用 |
public Outputstreamwriter(Outputstream os string charset) |
可以把原始的字节输出流按照指定编码转换成字符输出流( 重点) |
try {
File f = new File("src\\data5.txt");
OutputStream os = new FileOutputStream(f);
Writer osw = new OutputStreamWriter(os,"GBK");
Writer bw = new BufferedWriter(osw);
bw.write("我爱中国1~~");
bw.write("我爱中国2~~");
bw.write("我爱中国3~~");
bw.write("我爱中国4~~");
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
序列化对象

对象序列化:
-
作用: 以内存为基准, 把内存中的对象存储到磁盘文件中去, 称为对象序列化。
-
使用到的流是对象字节输出流: ObjectOutputStream

构造器 |
说明 |
public ObjectOutputStream(OutputStream out) |
把低级字节输出流包装成高级的对象字节输出流 |
对象反序列化:
使用到的流是对象字节输入流: ObjectdnputStream
作用: 以内存为基准, 把存储到磁盘文件中去的对象数据恢复成内存中的对象, 称为对象反序列化。


private static final long serialVersionUID = 1;
private String name;
private String loginName;
private transient String passWord;
总结:

打印流

打印流
作用: 打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指: PrintStream, PrintWriter 两个类。
可以实现打印什么数据就是什么数据, 例如打印整数97 写出去就是97 , 打印boolean 的true, 写出去就是true 。
PrintStream
构造器 |
说明 |
public PrintStream(OutputStream os) |
打印流直接通向字节输出流管道 |
public PrintStream(FiIe f) |
打印流直接通向文件对象 |
public PrintStream(String filepath) |
打印流直接通向文件路径 |
方法 |
说明 |
public void print(Xxx xx) |
打印任意类型的数据出去 |
PrintWriter
构造器 |
说明 |
public PrintWriter 〈OutputStream OS) |
打印流直接通向字节输出流管道 |
public PrintWriter (Writer w) |
打印流直接通向字符输出流管道 |
public PrintWriter (File f) |
打印流直接通向文件对象 |
public PrintWriter (String filepath) |
打印流直接通向文件路径 |
方法 |
说明 |
public void print()(xx xx) |
打印任意类型的数据出去 |
PrintStream 和PrintWriter 的区别
-
打印数据功能上是一模一样的, 都是使用方便, 性能高效( 核心优势)
-
PrintStream 继承自字节输出流OutputStream , 支持写字节数据的方法。
-
PrintWritedl* 承自字符输出流writer, 支持写字符数据出去。
总结:

输出语句重定向
属于打印流的一种应用, 可以把输出语句的打印位置改到文件。
PrintStream PS = new PrintStream("文件地址");
System.setOut(ps);
Properties

Properties 属性集对象
-
其实就是一个Map 集合, 但是我们一般不会当集合使用, 因为HashMap 更好用。
Properties 核心作用:
-
Properties 代表的是一个属性文件, 可以把自己对象中的键值对信息存入到一个属性文件中去。
-
属性文件: 后缀是.properties 结尾的文件, 里面的内容都是key=value,后续做系统配置信息的。
Properties的API:

总结:

IO框架
commons-io 概述
-
commons-io 是apache 开源基金组织提供的一组有关IO操作的类库, 可以提高IO功能开发的效率。
-
commons-io 工具包提供了很多有关io操作的类。有两个主要的类FileUtils, lOUtiIs
FileUtils 主要有如下方法:
方法名 |
说明 |
String readFiIeToString(File file, String encoding) |
读取文件中的数据,返回字符串 |
void copyFile(Fi1e srcFiIe, File destFile) |
复制文件 |
void copyDirectoryToDirectory(FiIe srcDir, FiIe destDir) |
复制文件夹 |

IOUtils.copy(new FileInputStream("E:\\wallpapercache\\img\\1.jpg"),
new FileOutputStream("E:\\wallpapercache\\img\\1-1.jpg"));
FileUtils.copyFileToDirectory(new File("E:\\wallpapercache\\img\\1.jpg"),
new File("E:\\"));
FileUtils.copyDirectoryToDirectory(new File("E:\\wallpapercache\\img"),
new File("E:\\new"));
FileUtils.deleteDirectory(new File("E:\\new"));
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现