流操作的步骤:
1.选择合适的流创建对象, 关联源(输入流)或关联目的(输出流)
2.传输数据
3.关闭资源(一定不要忘记)
之所以需要弄清规律是因为流对象太多, 开发时不知道用哪个合适
怎么办? 知道每个类的特点, 什么时候该用什么类就行了,
至于怎么使用, 去查API找方法
以下1,2,4,5,6,11都必须熟练掌握, 剩下的要能知道这些类是干什么用的.
1.FileInputStream && FileoutputStream
特点:
1) 字节流, 操作非文本的数据, 比如图片, 音乐, 视频, 等等.
2) 文件流, 用来操作文件的
了解: FileOutputStream的flush()方法是一个空方法, 也就是该方法无效
2.FileReader && FileWriter
特点:
1) 字符流, 操作文本数据
2) 文件流, 用来操作文件
3.InputStreamReader && OutputStreamWriter
特点:
1) 转换流, 字节转字符, 或者字符转字节
2) 可以指定码表
为什么使用?
1. 源或目的对应的设备是字节流, 但是操作的却是文本数据, 可以使用转换流作为桥梁, 提高对文本操作的
便捷
2. 一旦操作文本涉及到指定的编码表时必须使用转换流
有时候需要转换文本文件的编码
比如一个文本文件的编码是utf-8, 需要在程序中使用这个文件, 而中文操作系统的默认编码是gbk,
如果直接使用就会乱码, 就需要转换编码.
或者说一个文本文件的编码是utf-8, 这个文件的内容我要求转换成欧洲的字符编码iso8859-1, 那么
以指定的utf-8编码,使用InputStreamReader读入文件:
new InputStreamReader(inputStream, "utf-8"),
然后以指定的iso8859-1编码, 使用OutputStreamWriter来写出文件:
new OutputStreamWriter(outputStream, "iso8859-1")
有时候调用系统或别人的框架的一些方法返回的是一个字节流, 但是想要操作的实际上是字符数据,
想要使用字符流的一些比较便捷的方法, 就需要转换. 比如获取键盘输入:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
这样就能获取到控制台输入的一行字符串. 它比Scanner的nextLine方法好处在于它不会读取换行符
4.BufferedInputStream && BufferedOutputStream
特点: 字节流的包装器, 使字节流高效
包装流关闭时会自动关闭被包装的流
BufferedReader && BufferedWriter
特点: 字符流的包装器, 使字符流更高效
包装流关闭时会自动关闭被包装的流
5.ObjectOutputStream && ObjectInputStream
特点: 可以将对象写入文件(对象序列化), 或者从文件读取一个对象(对象反序列化)
当我们需要将一些数据保存起来, 或者说将一个对象的状态保存下来下次程序启动能继续使用(通常情况下是保存一个
集合)就需要使用对象序列化和反序列化. 比如你们的学生管理系统, 可以把学生信息保存到文件中, 下次启动程序就能
获取之前添加的学生信息.
注意: 将集合序列化时, 集合中的元素也必须实现Serializable(序列化)接口.
我们常用的集合基本都实现了序列化接口
transient 修饰的属性不会被序列化
静态属性不会被序列化
6.ByteArrayInputStream && ByteArrayOutputStream
特点: 1) 内存流
2) 字节流
3) close方法和flush方法是空方法, 也就是全都无效.
当对数据的读写操作都在内存中时使用
7.PrintStream && PrintWriter
特点: 1) 打印流, print系列的方法可以将数据的表示形式打印到流关联的目的地.
2) 输出流
PrintStream使用平台默认的字符编码将字符写入目的地,
当需要写入字节数据, 使用PrintStream, 写入字符数据, 应该使用PrintWriter
8.PipedInputStream && PipedOutputStream
特点: 可以用于不同线程之间流的读写
不能用于同一线程, 会出现死锁
9.DataInputStream && DataOutputstream
特点: 可以从流中读入或向流中写入基本数据类型的数据
10.LineNumberReader
特点: 1) 读入流
2) 可以获取读入的行号
11.RandomAccessFile
特点: 1) 可以从文件读入数据也可以写出数据到文件
2) 可以设置文件指针指定在文件的任意位置读入数据或写出数据
可以用来做多线程文件下载, 每个线程负责文件的一部分.
12.SequenceInputStream
特点: 合并流, 构造方法传入一个装有输入字节流的Enumeration, 就可以将Enumeration中的流的数据合并
需要合并文件时, 可以使用合并流.
close时会调用合并的那些流的close方法
Properties
与流结合的一个类, HashTable的子类, key和value都必须是String,
store() 将Properties的内容写入到流
load() 从流中读取数据到Properties中
想要知道开发时用哪个具体流需要通过四个明确:
1. 明确是数据源还是数据目的(也就是明确是要读数据还是写数据).
源 : InputStream Reader
目的 : OutputStream Writer
2. 明确数据是不是纯文本数据.
源 : 是纯文本 Reader
不是纯文本 InputStream
目的 : 是纯文本 Writer
不是纯文本 OutputStream
(到这里就可以明确需求中具体要用哪个体系)
3. 明确具体的设备.
源 :
硬盘 : File
键盘 : System.in
内存 : 数组
网络 : Socket流
目的 :
硬盘 : File
控制台 : System.out
内存 : 数组
网络 : Socket流
这一步已经完全可以明确具体使用哪个流对象了
4. 是否需要其它额外功能.
1. 是否需要高效(缓冲区)
是就加上buffer
2. 是否需要字节字符流之间转换
是 :
字节流转字符流 : InputStreamReader
字符流转字节流 : OutputStreamWriter 通过统一编码、解码的字符集可以解决中文乱码问题