2022-08-09 第二组刘禹彤 学习笔记
打卡28天
###学习内容
IO流(输入输出流)
File类不能操作文件的内容
1.按照流向分:
输入流:从硬盘上读取数据到内存(读)
输出流:从内存上写出数据到硬盘(写)
一个文件在传输过程中经历了多次拷贝,IO流性能本身就很低-----出现零拷贝,Nio附加题
2.按照操作单元分:
字节流:是一个字节一个字节的操作,二进制操作,操作任意类型文件
字符流:是一个字符一个字符的操作,一个字符两个字节,主要用来处理文本文件
(.txt,.java,.py,.html,。properties........................)
3.按照角色分:
节点流:直接操作一个特定的IO设备
处理流:在节点流的基础上,做进一步的处理
- JAVA中输入/输出流常用的流:
字节输入流 |
字节输出流 |
字符输入流 |
字符输出流 |
|
抽象基类 |
InputStream |
OutputStream |
Reader |
Writer |
访问文件 |
FileInputStream |
FileOutputStream |
FileReader |
FileWriter |
缓冲流 |
BufferedInputStream |
BufferedOutputStream |
BufferedReader |
BufferedWriter |
操作对象(只能字节操作) |
ObjectInputStream |
ObjectOutputStream |
- 流到底怎么用?
输入流:就是一点一点的往内存中读数据
1.字节输入流:1.创建一个FileInputStream对象
2.定义一个标记用来控制流的读取
3.循环读取,,如果读取到了-1,说明读到了末尾
4.关闭资源
注意:我们发现一个流读完就没有了,不能再读了
当一个流读完之后,会默认调用mark和reset方法来进行记录和重置,这个流就已经重置到了上次读完的位置,所以就无法再次读取到内容,并不是读完一次后就关闭了流
2.字节输出流:
FileOutputStream构造器:
boolean append参数:如果传入true,则代表在原有基础上追加,不覆盖
如果传入false,或者不传,覆盖原有内容
写的操作,目标文件如果不存在,会自动新建字符流
3.字符处理流(用的最多)
缓冲流:处理流--------------------- 外层流,内层流,外层关闭,内层也随之关闭
只能处理纯文本文件: .txt,.java,.html,.css.........---利用缓冲字符流来写一个文件的复制
- 序列化与反序列化:操作对象
(1)序列化:将对象写入到IO流中,将内存模型的对象变成字节数字,可以进行存储和传输
(2) 反序列化:从IO流中恢复对象,将存储在硬盘上或者从网络上接收的数据恢复成对象模型
(3)使用场景:所有可在网络上传输的对象都必须是可序列化的,否则会报错,所有保存在硬盘上的对象也必须可序列化
(4)序列化版本号:反序列化必须拥有class文件,但随着项目的升级,class文件也会升级序列化保证升级前后的兼容性
java序列化提供了一个版本号,版本号是可以自由指定的,如果不指定,JVM会根据自己计算的一个版本号,所以无法匹配,则报错!!
不指定版本号,还有一个隐患,不利于JVM的移植,可能class文件没有改,但是不同的 jvm计算规则不一样,导致无反序列化
如果只修改了方法,反序列化是不受影响的,无需修改版本号,修改了静态变量static,瞬态变量transient,反序列化也不受影响,无需修改版本号
总结: 1.所有需要网络传输的对象都需要实现序列化接口
2.对象的类名,实例变量都会被序列化;方法,类变量,transient变量不会被序列化
3.如果想让某个变量不被序列化,可以用transienrt修饰
4.序列化对象的引用类型成员变量也必须是可序列化的,否则会报错
5.反序列化时必须有序列化对象的class文件
6.如果同一对象被序列化多次,只有第一次序列化为二进制流,以后都只保存系 列化的版本号
7.建议所有的可序列化类都加上版本号
1)我们最终会把所有的.class文件打包,把这个包部署到服务器上,从始至终,.java仅仅是我们程序员写的,给程序员看的,.java甚至不会参与到打包中,不会出现在服务器上
2)运维人员去服务器部署项目,部署的就是一堆.class,我们的.properties属性文件不会参与编译,一旦数据库升级,改变此文件即可,否则要改变源码,很耗费资源
###学习心得
今天开始正式学习IO流,概念理解的还可以,但是做案例不太好,视频要反复观看
###掌握情况:一般
###课上练习
import util.IOUtil; import org.junit.Test; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Objects; public class Ch03 { @Test public void test03(){ System.out.println(Objects.nonNull("null")); } @Test public void test02() { OutputStream outputStream = null; try { outputStream = new FileOutputStream("D:\\javalyt\\vscode\\aaa.txt",true); // 一个字节一个字节的写 outputStream.write("\r\n".getBytes()); outputStream.write("八月正午的阳光都没你耀眼".getBytes()); System.out.println("数据写出成功..."); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { IOUtil.closeIO(null,outputStream); // try { // if(Objects.nonNull(outputStream)){ // outputStream.close(); // } // } catch (IOException e) { // throw new RuntimeException(e); // } } } @Test public void test01() { OutputStream outputStream = null; try { // 一个字节一个字节的写 outputStream = new FileOutputStream("D:\\javalyt\\vscode\\aaa.txt",true); outputStream.write(98); System.out.println("数据写出成功..."); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { try { outputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
###运行结果