FileInputStream与FileoutputStream
FileInputStream类可以将一个文件的内容作为字节流读取,我们看一下源码:
FileoutputStream是使用字节流方式将数据写入文件,实现与FileinputStream一样,一个是字节流方式读文件,一个是字节流方式写文件。
需要注意的是,FileInputStream和FileoutputStream是直接从文件中读取数据到应用程序内存中,或直接从程序中写到文件上,没有缓冲区的概念(注:FileoutputStream的flush方法没有实现内容)。
FilterInputStream、FilterOutputStream与装饰者模式
查看FilterInputStream与FilterOutputStream的源码,我们并没有看出有什么特殊的实现,只是内置了InputStream和OutputStream,并在对应的方法上调用了实例in和实例out的方法,这就是装饰者模式。主要是提供与真实类一样的功能,并且将请求转给真实的类,并且在特定情况下可以扩展功能,这种扩展不会影响原类的功能。使用装饰器模式,感觉像实现了复杂一点的继承关系。
BufferedInputStream与BufferedOutputStream
BufferedInputStream增加了缓冲区,不像FileInputStream每次一个字节一个字节的读取,而是一次读取一块数据到内存缓冲区中,再从缓冲区中读取字节流,减少了访问磁盘的次数,而在内存缓冲区读取相当于内存级别的操作,所以,读取效率更快。BufferedInputStream是FilterInputStream的子类,也就是说,BufferedInputStream可以指定任意一个InputStream对象为装饰器的实际对象,这里可以理解成,即可以读取网络I/O,又可以读取磁盘I/O。
然后读一下源码看一下具体实现:
BufferedOutputStream增加了缓冲区,可以每次向缓冲区中写字节流,然后再统一写到磁盘或者网络,减少IO的次数,提升效率。
BufferedOutputStream的flush方法,会调用一次flushBuffer方法,执行装饰器真实类的写方法,并且调用真实类的flush方法。(FileOutputStream方法的flush方法有什么作用?)
DataInputStream与DataOutputStream是一个与平台无关的输入输出流的类,提供基本数据类型的输入和输出操作。查看源码这两个类实现了DataInput和DataOutput接口,并且继承自FilterInputStream和FilterOutputStream。所以这两类仍然使用了装饰器模式,并且实现DataInput与DataOutput中的基本数据类型的输入和输出操作。
RandomAccessFile与常见的输入输出类不同,查看类图可以看出,它实现了DataInput和DateOutput接口,而底层的读、写等方法都是JNI方法,所以它与其他的输入输出类不同,而且它同时提供读写两种操作,因为操作比较灵活,所以命名为Random访问文件。
PipedInputStream与PipedOutputStream是建立Java两个线程之间的管道,两个线程通过建立起来的管道进行输入和输出字节流。
查看源码可以看出:
public class PipStream { PipedInputStream inputStream; PipedOutputStream outputStream; public void read() { inputStream = new PipedInputStream(4096); outputStream = new PipedOutputStream(); try { outputStream.connect(inputStream); } catch (IOException e) { e.printStackTrace(); } Thread thread1 = new Thread(() -> { try { int data = inputStream.read(); while (data != -1) { System.out.println(data); data = inputStream.read(); } } catch (IOException e) { e.printStackTrace(); } }); thread1.start(); Thread thread2 = new Thread(() -> { int i = 0; while (true) { if (i >= 100) { break; } try { outputStream.write(1); } catch (IOException e) { e.printStackTrace(); } i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread2.start(); } public static void main(String[] args) { new PipStream().read(); }}
ObjectInputStream与ObjectOutputStream实现的是对基本类型或对象的序列化与反序列化操作,也是装饰器模式,可以将对象或者基本类型的数据存入文件或者网络中,再通过文件和网络重新读取序列化之前的基本类型或对象数据。应用场景包括实现对象序列化为二进制数据,再反序列化从二进制数据变成对象。
public class ObjectStream { private static String readPath = "C:\\Users\\Administrator\\Desktop\\person.txt"; public static void main(String[] args) { Person person = new Person(); person.setPwd("1234"); person.setUid("4321"); try { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(readPath)); objectOutputStream.writeObject(person); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(readPath)); Object object = objectInputStream.readObject(); Person p = (Person) object; System.out.println("pwd:" + p.getPwd() + ",uid" + p.getUid()); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } }}
InputStreamReader与OutputStreamWriter是将基于字节流的InputStream和OutputStream转化成基于字符流的Reader和Writer,构造方法需要指定字符编码,以防止字节转成字符时候乱码,查看源码发现,底层都是通过StreamEncoder来实现的,包括读取策略,写入策略,字符编码,缓冲区等。
FileReader、FileWriter与FileInputStream、FileoutputStream类似,都是从一个文件中进行读取和写入,只不过FileReader和FileWriter是以字符形式,FileReader和FileWriter是InputStreamReader和OutputStreamWriter的子类,只是包装了一下FileInputStream、FileoutputStream类。
PipedReader、PipedWriter可以将管道中的数据以字符形式读取和写入,其工作原理与PipedInputStream和PipedOutputStream类似。
BufferedReader、BufferedWriter为Reader、Writer类提供缓冲区,实现原理与BufferedInputStream和BufferedOutputStream类似,但不相同,主要区别就是一个读取字节,一个读取字符(文本),BufferedReader还提供readLine方法,使读取文本更加方便,BufferedWriter也可以写入换行符(换行符是在构造方法中获取系统的换行标识符)。
FilterReader、FilterWriter是装饰器类,用来扩展Reader、Writer,目前来看没有什么实际使用场景。
其他特殊IO类
ByteArrayInputStream、ByteArrayOutputStream与CharArrayReader、CharArrayWriter是字节数组和字符数组的输入输出对象,它们都是通过读取和写入字节或字符数组实现。(注:关闭对于这四个类来说,没有意义)
LineNumberReader是BufferedReader的子类,主要是增加了LineNumber的概念。
SequenceInputStream是Java提供的可以将两个或者多个InputStream合并成一个,按照顺序分别读取每个输入流中的数据。
PushbackInputStream、PushbackReader是IO API提供的具有回退机制的输入字节流,输入字符流。