首
java.io中有百万计的类,如何找到自己需要的部分?
流
IO涉及到一个“流”stream的概念,可以简单理解成数据从一个源头到一个目的地。明白数据从哪来,要到哪里去,数据流中是字节还是字符之后,才能找到自己需要的类。
字节流
根据流中内容可以分为字节流(一般处理二进制数据)和字符流(一般处理文本数据)。
字节流的两个基类:InputStream和OutputStream,分别表示流的源头和流的目的地。如FileInputStream表字节流的源头是文件,即从文件中拿数据。FileOutputStream表字节流的目的地是文件,即向文件中输送。
此外,为了让流具有缓冲作用,还提供了BufferedInputStream和BufferedOutputStream。
比如将一个对象序列化进文件:
FileOutputStream fs = new FileOutputStream("file.ser");
ObjectOutputStream os = new ObjectOutputStream(fs); //obj通过ObjectOutputStream向fs输出
os.writeObject(obj);
将数据装入文件,流的目的地是文件,故选择FileOutputStream。流中内容为字节,而要输入的数据是对象,为了将对象向字节进行转换,插入了ObjectOutputStream。当对象进入ObjectOutputStream后,obj会被转为字节,之后字节进入FileOutputStream流,最终“流”向文件。
可以看到,每个stream都有自己的功能,我们只需要拼接它们就好了。
字符流
当处理文本数据时,使用字符流。两个基类Reader和Writer,分别表示流的源头和目的地。如FileReader表字符流的源头是文件,即从文件中读数据。FileWriter表字符流的目的是文件,即向文件写数据。
除了提供了缓冲功能BufferedReader和BufferedWriter外,还提供了InputStreamReader和OutputStreamWriter用来将InputStream和OutputStream转为Reader和Writer,方便进行文本处理。
例如,从一个socket中读取文本:
Socket soc = new Socket("xx", xx);
InputStreamReader ir = new InpuStreamReader(soc.getInputStream());
BufferedReader br = new BufferedReader(ir)
String msg = br.readLine()
从socket读取数据,即socket向流中输入数据,流的源头是socket,故要获取socket的输入流。因为我们要读取文本内容,而不想读取字节数据,故通过InputStreamReader将字节流转为字符流。
为了让流具有缓冲作用,再接上BufferedReader,之后便可以从流中读取数据了。
那向socket中发送文本数据呢?
可以把上面的数据改改,Input改成Output,reader改成writer。这里说另一个类PrintWriter,类重载了很多构造方法,能够接受String,File,OutputStream以及Writer,流内数据类型的转换自己可以完成,且自带缓冲。
Socket soc = new Socket("xx", xx);
PrintWriter pw = new PrintWriter(soc.getOutputStream());
pw.println("xx")
尾
流需要考虑三个方面:数据从哪来,数据到哪去,流中数据的类型。之后再根据自己的业务需求将不同功能的流拼接即可。