现在返回来看之前一直觉得迷迷糊糊的IO这一部分,顿时真的觉得阔然开朗。所以现在觉得自学的顺序应该是这样的,先过一遍基本的知识体系,然后通过实践、练习和项目来巩固,最后再回头复习这些知识点,真的会有不一样的体会。下面稍稍对自己了解到Java的IO体系做一个小小总结。
1.Java流式输入/输出的原理:
在Java程序中,对于数据的输入/输出操作都是以流(stream)的方式进行的,JDK提供了各种各样的流,可以获取不同种类的数据,程序可以通过标准的方法输入或输出数据。
2.Java流的分类:
java.io包中定义了多个流类型(类或者抽象类)来实现输入/输出功能;可以从不同的角度对其进行分类:
<1.按数据流的方向的不同可以分为输入流和输出流(这里的方向都是相对于程序而言)。
<2.按处理数据单位的不同可以分为字节流和字符流。
<3.按照功能不同可以分为节点流和处理流。
java.io提供了所有流类型都分别继承了以下四个抽象类的类型:
字节流:InputStream、OutputStream
字符流:Reader、Writer
值得注意的是以上四个类都是抽象类,不能直接创建实体。
需要特别小心的是:字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。
3.节点流和处理流:
节点流可以从一个特定的数据源(节点)读写数据(如:文件、内存)。
处理流是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
常见的节点流可以根据上面提到的四个抽象类分为四类:
<1.InoutStream:继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit),主要有FileInputStream、ByteArrayInputStream、StringBufferInputStream。
<2.OutputStream:继承自OutputStream的流都是用于向程序中输出数据,且数据的单位为字节(8bit),主要有FileOutputStream、ByteArrayOutputStream。
<3.Reader:继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit),主要有CharArrayReader、StringReader、FileReader。
<4.Writer:继承自Writer的流都是用于向程序中输出数据,且数据的单位为字符(16bit),主要有CharArrayWriter、StringWriter、FileWriter。
处理流的类型(分类方式同上面的节点流一样):
<1.InoutStream:主要有BufferedInputStream、FilterInputStream、ObjectInputStream、DataInputStream。
<2.OutputStream:主要有BufferedOutputStream、FilterOutputStream、ObjectOutputStream、DataOutputStream、printStream。
<3.Reader:主要有BufferedReader、FilterReader、InputStreamReader。
<4.Writer:主要有BufferedWriter、FilterWriter、OutputStreamWriter、PrintWriter。
下面将详细介绍各个处理流。
4.缓冲流:
缓冲流套接在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。
JDK提供的缓冲流主要有四种:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream。
对于输出的缓冲流,写出的数据会现在内存中缓存,使用fluse()方法将会使内存中的数据立刻写出。
5.转换流:
InputStreamReader、OutputStreamWriter用于字节数据到字符数据的转换,分别需要和InputStream、OutputStream进行套接,转换流在构造的时候可以指定其编码集合。
例如:
InputStream isr = new InputStreamReader(System.in,"ISO8859-1");
注意:值可以进行字节到字符的转换,而不存在字符到字节的转换。
System.in(标注输入)是一个InputStream子类的实体。而System.out是PrintStream类的实体。System提供了setOut()可以设置输出的位置。
6.数据流:
DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,它们提供了可以存取与机器无关的Java原始类型数据的方法,如:int、double等类型(大于16bit的的大小)。
7.Print流:
PrintWriter、PrintStream都属于输出流,分别使用与字符和字节。
PrintWriter、PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息,他们都有自动flush的功能。
8.Object流:
ObjectInputStream、ObjectOutputStream直接将Object对象写入或读出。
需要注意的是这个Object类需要实现序列化Serializable接口,Serializable是一个标志性的接口,其中没有具体的方法;此外其中声明了transient关键字的属性将不被进行序列化;externalizable接口继承了Serializable,其中的方法可以让用户自己定义序列化的方式。