Java中的IO流总结

IO可以分为文件IO和Socket IO,本篇主要总结文件IO。

一、常用的流

下图就是Java中常见的文件IO流。

1.流的分类

①输入流和输出流。

按照流向:可分为输入流和输出流。

这里输入输出涉及到方向问题,通常是以内存(程序运行在内存)的角度来考虑的。所以,从硬盘到内存是内存输入,从内存到硬盘是输出。

如果数据是从服务器端到客户端,这种情况下,服务端的内存负责将数据输出到网络里,所以是输出,Client端的内存负责从网络读取数据,因此是输入。

②字节流和字符流

字节流操作的是8位的字节(1Byte),而字符流操作的是16位的字符(2Byte)。

③节点流和处理流

按照流的角色来分,可以分为节点流和处理流。

可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流,节点流也被成为低级流。

处理流则用于对已存在的流进行连接或封装,顾名思义,处理就是对流进行功能处理。处理流也被称为高级流。实际上,Java使用处理流来包装节点流是一种典型的装饰器模式,通过使用处理流来包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。因此,处理流也被称为包装流

2.IO流的体系

访问文件:

  FileInputStream,FileOutputStream

  FileReader,FileWriter

  RandomAccessFile:并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组)。可读写文件,还可以随机读写(跳转到文件的任意地方来读写数据)。

访问数组:

  • 字节数组:ByteArrayInputStream, ByteArrayOutputStream
  • 字符数组:CharArrayReader, CharArrayWriter

访问字符串:

  StringReader,StringWriter

访问管道(管道流,用于线程间通信):

  PipedInputStream,PipedOutputStream,PipedReader,PipedWriter。

缓冲流:
  BufferedInputStream, BufferedOuputStream

  BufferedReader, BufferedWriter

转换流(用于将字节流转换为字符流):

  InputStreamReader,OutputStreamWriter

对象流(用于对象序列化和反序列化):

  ObjectInputStream,ObjectOutputStream

打印流:

  PrintStream,PrintWriter

推回输入流: 

  PushbackInputStream,PushbackReader

流的串行化:

  SequenceInputStream

3.其它

①Java的标准输入输出分别通过System.in和System.out来代表,在默认情况下它们分别代表键盘和显示器。

②JVM读写其它进程的数据:

Process p = Runtime.getRuntime().exec(xxx);
//获取子进程的错误流
InputStream error=p.getErrorStream();
//获取子进程的输入流
InputStream in=p.getInputStream();
//获取子进程的输出流
OutputStream out=p.getOutputStream();

这里的输入流和输出流容易混淆。如果让子进程读取程序中的数据,则应该使用输出流。要站在Java程序的角度来看问题,子进程读取Java程序的数据,就是让Java程序把数据输出到子进程中(就像把数据输出到文件中一样,只是现在由子进程代替了文件节点),所以应该使用输出流。

④流的关闭

在使用处理流包装了底层节点流之后,关闭IO时,只需要关闭上层的处理流即可。系统会自动关闭被处理流包装的节点流。

⑤文本文件的读写

文本文件的输出

PrintWriter out = new PrintWriter("employee.txt", "UTF-8"); 
等价于
PrintWriter out = new PrintWriter( new FileOutputStream("employee.txt"), "UTF-8"); 

文本文件的读取:

//短文本的读取
String content = new String(Files.readAllBytes(path), charset); 

//按照行的形式读取
List<String> lines = Files.readAllLines(path, charset); 

//(传统方式)读取文件写法,一行行的读
InputStream inputStream = . . .; 
try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream))) 
{ 
    String line; 
    while ((line = in.readLine()) != null) { 
        do something with line 
    } 
}

//(新方式)大文本的读取
try (Stream<String> lines = Files.lines(path, charset)) { 
    ... 
}

二、IO中的装饰者模式

装饰器模式

posted @ 2019-06-24 23:12  静水楼台/Java部落阁  阅读(321)  评论(0编辑  收藏  举报