为啥又参考(copy)别人的呢?是为了站在前人的肩膀上学到更多的东西。(我能说是因为懒?)
参考了:
https://www.jianshu.com/p/715659e4775f
https://www.cnblogs.com/CQqf/p/10795656.html
一:看图

-
字节流和字符流的区别:
字节流读取单个字节,字符流读取单个字符(一个字符根据编码的不同,对应的字节也不同,如 UTF-8 编码是 3 个字节,中文编码是 2 个字节。)字节流用来处理二进制文件(图片、MP3、视频文件),字符流用来处理文本文件(可以看做是特殊的二进制文件,使用了某种编码,人可以阅读)。简而言之,字节是个计算机看的,字符才是给人看的。 -
Reader、Writer、InputStream、OutputStream都是抽象类。
-
从数据来源或者说是操作对象角度看,IO 类可以分为:
1、文件(file):FileInputStream、FileOutputStream、FileReader、FileWriter
2、数组([]):
2.1、字节数组(byte[]):ByteArrayInputStream、ByteArrayOutputStream
2.2、字符数组(char[]):CharArrayReader、CharArrayWriter
3、管道操作:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
4、基本数据类型:DataInputStream、DataOutputStream
5、缓冲操作:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
6、打印:PrintStream、PrintWriter
7、对象序列化反序列化:ObjectInputStream、ObjectOutputStream
8、转换:InputStreamReader、OutputStreWriter
9、字符串(String:StringBufferInputStream、StringBufferOutputStream、StringReader、StringWriter
二:这个博主对源代码分析的非常棒,我也是看他的博客学习的https://blog.csdn.net/panweiwei1994/article/details/78046000
三:简单自我总结上面博客的学习(个人总结,不一定适用你)
1:ByteArrayInputStream(内存操作流,用于内存和程序之间数据交换。这个东西比较鸡肋)
- ByteArrayInputStream属于字节型输入流,包含一个内部缓冲区(byte类型的数组。),该缓冲区包含从流中读取的字节。但是一开始这个buf数组是没有空间的,你在构造ByteArrayInputStream的时候必须传进去一个byte数组 。
protected byte buf[];
- 我其实一直不是很理解,InputStream到底是往哪里read,这个类就很好的说明了。是我们要获得数据,所以我们byte[] temp=new byte[100],然后把temp作为ByteArrayInoutStream的构造参数传进去,最后的我们要的数据其实就在temp里面。
- close()方法没有作用:因为ByteArrayInputStream使用的是我们自己传进去的空间。所以java回收机制会帮我们搞定数组空间的回收。
2:ByteArrayOutputStream(内存操作流,用于内存和程序之间数据交换。我往内存write,其实就是往这个流内部数组write。我想要内部数组的数据,直接toByteArray就好)
- ByteArrayOutputStream属于字节型输出流,该输出流中的数据被写入到一个byte数组里。byte数组会随着被写入其中的数据的增长而增长。
- ByteArrayOutputStream可以通过writeTo( OutputStream out)实现输出流之间数据的复制
- ByteArrayOutputStream 的close方法无效,无法关闭此输出流。
3. PipedInputStream和PipedOutputStream
- 作用:管道输入流输出流,操作系统有学过的噢,线程之间进行通信的手段之一就是通信。
- 怎样使用呢?你可以在A线程中new一个内部的PipedInputStream(pis),然后在B线程中new一个内部的PipedOutputStream(pos),然后pis.connect(pos),连接之后,启动线程。如果我们B线程在run方法里面把数据写进去,A线程在run方法里面把读取的信息读取出来。
-
PipedOutputStream的write()其实就是PipedInputStream里面的recieve(),为啥?
我们可以看到write方法里面有一个sink,这个其实就是PipedInputStream。(PipOutputStream内部有一个PipedInputStream叫sink,在connect的时候,给sink赋值),然后sink.receive()。
也就是说,PipedOutputStream进行write的时候,已经把值传入到了PipedInputStream的内部数组中。
4. FilterInputStream、FilterOutputStream
FilterInputStream、FilterOutputStream是过滤器字节输入输出流。它们的主要用途在于封装其他的输入输出流,为它们提供一些额外的功能。
- FilterInputStream、FilterOutputStream并没有提供什么装饰功能。
- FilterInputStream、FilterOutputStream的子类可进一步重写这些方法中的一些方法,来提供装饰功能。
- FilterInputStream装饰功能的实现的关键在于类中有一个InputStream字段,依赖这个字段它才可以对InputStream的子类提供装饰功能。FilterOutputStream也是如此。
5. BufferedInputStream与BufferedOutputStream
- 是继承FilterInputStream和FilterOutputStream的装饰流。
- 作用:BufferedInputStream是缓冲输入流,作用是为另一个输入流添加一些功能,比如缓冲输入功能以及支持mark和reset方法的能力。
- 咋使用呢?
里面包装InputStream、 OutputStream就行。 -
mark(int readlimt):标记当前pos这个地方(不是参数readlimt),下次reset的时候,会直接回到这个地方。
6.DataInputStream和DataOutputStream
- 是一个处理流,可以放int等类型的数据。构造的时候要传入节点流。
7.FileInputStream和FileOutputStream
- FileInputStream和ByteArrayInputStream一样,read的时候,都是要传入一个byte类型的数组。其实数据是读到这个数组了。不同的是,构造FileInputStream的时候不能传入这个接收byte数组。而ByteArrayInputStream是构造对象的时候就需要这个数组。
FileOutputStream就是写嘛,一个write方法。
8.Reader和Writer和前面的都差不多。

网友评论