3.缓冲流
3.1缓冲流的简介
-
基本介绍
给普通的IO流,套上⼀个缓冲区。所有的使⽤缓冲流进⾏的读写操作,都是和缓冲区进⾏交互的, 避免了频繁的IO操作。这样⼀来, 带来的好处就是可以提⾼读写的 效率。 这个缓冲区, 其实是⼀个数组。
-
缓冲流的作⽤
为了提⾼读写的能⼒,本身没有读写的能⼒,要想进⾏读写就必须借助于字符流/字节流实现.
可以将缓冲流类⽐于催化剂或者⾼速的⼩⻋
-
常⻅的缓冲流:
-
BufferedInputStream : 缓冲字节输⼊流
-
BufferedOutputStream :缓冲字节输出流
-
BufferedReader :缓冲字符输⼊流
-
BufferedWriter :缓冲字符输出流
-
-
字符流和缓冲字符流对⽐
使⽤缓冲流实现读写的步骤与字符流⼀样,只是需要我们先通过构造⽅法传⼊⼀个字符流对象.同时缓冲流可以提⾼读写效率.
-
总结:
⼤家在使⽤流读写数据时,尽量使⽤缓冲流,缓冲流中尽量使⽤缓冲字符流,在字符缓冲流中⽐缓冲字节流多了readLine()和newLine()⽅法.
3.2缓冲字符流中的特殊⽅法
BufferedReader 类中多了⼀个⽅法 readLine()
-
意义: 读取缓冲流中的⼀⾏数据,可以逐⾏读取。⼀直到读取到的数据是null,表示数据读取完了, 没有下⼀⾏数据了。
-
注意事项: readLine() 是逐⾏读取,但是,只能读取到⼀⾏中的内容,并不能读取⾛换⾏符。
BufferedReader 类中多了⼀个⽅法 newLine()
-
写换⾏符 ,不同的系统使⽤的默认换⾏符不⼀样 windows系统 \r\n linux \n
-
意义: ⽆参的⽅法, 写⼀个换⾏符,⽀持跨平台(平台⽆关性
LineNumberReader是BufferedReader的⼦类,不能读.但是可以提⾼效率,特有功能:设置⾏号,获取⾏号
4.装饰设计模式
-
设计模式简介
设计模式,前⼈总结出来的对⼀些常⻅问题的解决⽅案,后⼈直接拿来使⽤.
常⽤的设计模式:单例,⼯⼚,代理,适配器,装饰,模板,观察者等,⼀共有23种
-
装饰设计模式
基于已经实现的功能,提供增强的功能.
-
装饰设计模式特点
装饰设计模式的由来就来⾃于对缓冲流的实现.
从缓冲流的⻆度讲解
1.使流原来的继承体更加的简单
2.提⾼了效率
3.由于是在原有的基础上提⾼增强的功能,所以他还要属于原来的体系
-
如果⾃⼰设计装饰设计模式,怎么处理?
1.原来的类 Test---Reader
2.装饰类 BTest----MyBufferedReader
步骤:
1.让BTest 继承⾃Test
2.在BTest内有⼀个Test类型的成员变量
3.通过BTest内⼀个带参数的构造⽅法接收外部传⼊的⼀个Test类型的对象,交给内部 的Test的属性
4.在实现功能的时候,调⽤传⼊的Test类型的对象实现原有的功能,⾃⼰实现增强的功能.
5. Scanner类
5.1简介
这个类,并不是⼀个IO流。是⼀个扫描器,这个类最主要的作⽤,是从⼀个⽂件中 或者从⼀个流中浏览数据。在这个类中封装了若⼲个⽅法,⽅便了数据的读取。
5.2 API
方法 | 描述 |
---|---|
next() | 读取⼀个单词,遇到空格或者换⾏符就不再读取了。 |
hasNext() | 判断是否还有下⼀个单词可以读取。 |
nextLine() | 读取⼀⾏内容,遇到换⾏符就不再读取了。 |
hasNextLine() | 判断是否还有下⼀⾏可以读取。 |
注意事项:
这⾥nextLine和BufferedReader中的readLine都可以读取⼀⾏数据。但是区别在 于:结束条件不同。
-
BufferedReader: 如果读取到的数据是null, 说明没有下⼀⾏数据了。
-
Scanner: 如果没有下⼀⾏了,再去读取,会出现异常。 所以, 此时的结束条件 是 hasNextLine() 为false。
6.标准输入输出流
6.1简介
-
标准输⼊流: System.in : “标准”输⼊流。此流已打开并准备提供输⼊数据。通常,此流对应于键盘输⼊或者由主机环境或⽤户指定的另⼀个输⼊源。
输⼊源:可以发送数据到内存的设备
输出源:可以接收内存的数据的设备
1.当前的流已经打开并关联了输⼊源--键盘
2.如果不想让键盘充当输⼊源,可以通过setIn进⾏更换
3.是⼀个字节流
-
标准输出流: System.out : 标准”输出流。此流已打开并准备接受输出数据。通 常,此流对应于显示器输出或者由主机环境或⽤户指定的另⼀个输出⽬标。
7.打印流
7.1打印流分类
除了拥有输出流的特点之外,还有打印的功能.
-
字节打印流:PrintStream
-
字符打印流:PrintWriter
7.2字节打印流
字节打印流⽀持的设备:
-
1. File类型的⽂件
-
2.字符串类型的⽂件
-
3.字节输出流
7.3字符打印流
-
字符打印流⽀持的设备:
-
1. File类型的⽂件
-
2.字符串类型的⽂件
-
3.字节输出流
-
4.字符写出流
-
-
注意点:
-
⽅法:public PrintWriter(Writer out, boolean autoFlush)
-
autoFlush - boolean 变量;如果为 true,则 println、printf 或 format ⽅法将 ⾃动刷新输出缓冲区
-
但是执⾏print⽅式时需要⼿动刷新
-
8.序列化流
8.1简介
-
将短期存储的数据实现⻓期存储,这个过程对应的流就是序列化流
-
数据的存储分成两类:
-
1.短期存储:存放在内存中,随着程序的关闭⽽释放---对象,集合,变量,数组
-
2.⻓期存储:存储在磁盘中,即使程序关闭了,数据仍然存在------⽂件
-
-
序列化:将数据从内存放⼊磁盘,可以实现数据的⻓久保存
-
反序列化:将数据从磁盘放回内存
8.2注意事项
-
ObjectInputStream、 ObjectOutputStream, 主要是⽤来做对象的序列化和反序列化的。
-
序列化、 反序列化, 是对象的持久化存储的⼀种常⽤⼿段。
-
所有的要序列化到本地的类的对象, 类必须实现 java.io.Serilizable 接⼝。
实现了Serializable接⼝的类可以达到的⽬的:
1.可以进⾏序列化
2.进⾏序列化的类的元素都必须⽀持序列化
3.可序列化类的所有⼦类型本身都是可序列化的。
4.接⼝本身没有⽅法或字段,只是⽤来表示可序列化的语义
-
如果需要序列化多个⽂件到本地,尽量不要序列化到⼀个⽂件中。如果需要序列化多个⽂件到本地,通常采⽤的⽅式,是存集合。将多个对象存⼊⼀个集合中,将这个集合序列化到本地。
-
常⻅问题总结
注意点:
-
ClassNotFoundException:当前的类没有找到
分析:将Person对象进⾏序列化之后,将Person类删除,再进⾏反序列化的时候出现了 异常
原因:反序列化在执⾏的时候依赖字节码⽂件,当类没有了,字节码⽂件⽆法创建,反序列化失败
-
java.io.InvalidClassException ⽆效的类
出现的原因:没有声明⾃⼰的serialVersionUID,⽽使⽤系统的.在进⾏反序列化的时 候,类被改动了,系统认为现在的类
已经不是原来的类了(在使⽤系统的id进⾏识别的时候,重写给Person设置了id),认为 此类⽆效
3.使⽤系统的serialVersionUID与⾃定义的ID的区别?
使⽤系统的,序列化和反序列化,id不能⼿动设置,使⽤的是编译器默认⽣成的,⼀旦类 发⽣了改动,id会重新赋值
使⽤⾃定义的,序列化和反序列化,id不会发⽣改变,所以当反序列化的时候,即使对 Person类进⾏了⼀些改动,也能继续反序列化
-