IO流序列化与反序列化

按照不同的分类方式,可以将流分为不同的类型
输入流:只能从中读取数据,不能向其写入数据(内存从硬盘中读取)。
输出流:只能向其写入数据,而不能从中读取数据(内存从硬盘中输出)。

输入输出流
Java的输入流主要由InputStream和Reader作为基类,而输出流则主要由OutputStream和Wrter作为基类。他们都是抽象基类,无法直接创建实例

字节流和字符流
字节流和字符流的用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同——字节流操作的数据单元是8位的字节而字符流操作的数据单元是16位的字符。
字节流主要由InputStream和OutputStream作为基类,而字符流则主要由Reader和Writer作为基类。

节点流和处理流
按照流的角色来分,可以分为节点流和处理流。
可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流,节点流也被称为低级流(Low Level Stream)。

处理流则用于对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能。处理流也被称为高级流。

实际上,Java使用处理流来包装节点流是一种典型的装饰器设置模式,通过使用处理流来包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入/输出功能。因此处理流也被称为包装流。

Java把所有设备里的有序数据抽象成流模型,简化了输入/输出处理,理解了流的概念模型也就了解了JavaIO

InputStream 和Reader 是所有输入流的抽象基类,本身并不能创建实例来执行输入,但它们将称为所有输入流的模板,所以它们的方法是所有输入流可以使用的方法。

在InputStream里包含如下3个方法。

int read():从输入流中读取单个字节返回所读取的字节数据(字节数据可直接转换为int类型)

int read(byte[] b):从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数

int read(byte[] b,int off,int len)从输入流中最多读取len个字节的数据,并将其存储在字节数组b中,放入数组b中式,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。

在Reader里包含如下:3个方法
int read():从输入流中读取单个字符返回所读取的字符数据(字符数据可直接转换为int类型)

int read(char[] cbuf):从输入流中最多读取cbur.length个字符的数据,并将其存储在字符数组cbuf中,返回实际读取的字符数。

int read(char[] cbuf,int off,int len):从输入流中最多读取len个字符的数据,并将其存储在字符数组cbuf中,放入数组cbuf中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字符数。

处理流的用法

转换流
输入/输出流体系中还提供了两个转换流,这两个转换流用于将字节流转换成字符流其中InputStreamReader将字节输入流装换成字符流,OutputStreamWriter将字节输出流转换成字符输出流

RandomAccessFile
RandomAccessFile是java输入/输出流体系中功能最丰富的文件内容访问类,他提供了众多的方法来访问文件内容,它即可以读取文件内容,也可以向文件输入数据。与普通的输入/输出流不同的是,RandomAccessFile支持“随机访问”的方式,程序可以直接跳转到文件的任意地方来读写数据。
因为RandomAccessFile可以自由访问文件的任意位置,所以如果我们希望之访问文件部分内容,而不是把文件从头到尾,使用RandomAccessFile将更好的选择。
与OutputStream,Writer等不同的是,RandomAccessFile可以不从开始的地方开始输出,所以RandomAccessFile可以向已存在的文件后追加内容。因此,如果程序需要向已存在的文件后追加内容,则应该使用RandomAccessFile.
RandomAccessFile 对象也包含了一个记录指针,用以表示当前读写处的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头(也就是0处),可以自由移动改记录指针,既可以向前移动,也可以向后移动。RandomAccessFile包含了如下两个方法来操作文件记录指针。
long getFilePointer():返回文件记录指针的当前位置。
void seek(long pos): 将文件记录指针定位到pos位置。
RandomAccessFile即可以读文件,也可以写,所以它即包含了完全类似于InputStream的3个read()方法,其用法和InputStream的3个read()方法完全一样,也包含了完全类似于OutputStream的3个write()方法,其用法和OutputStream的3个write()方法完全一样。除此之外,RandomAccessFile还包含了一系列的readXxx()和writeXxx()方法来完成输入、输出

对象序列化
对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制允许把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存再磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流(无论是从磁盘中获取的还是通过网络获取的),都可以将这种二进制流恢复成原来的Java对象
序列化的含义和意义
序列化机制允许将实现序列化的java对象转换成字节序列化,这些字节序列化可以保存在磁盘上,或通过网络传输,以备以后重新恢复复原成原来的对象。序列化机制使得对象可以脱离程序的允许而独立存在的。
对象的序列化(Seriallze)指将一个Java对象写入IO流中,与此对应的是,对象的反序列话(Deserialize)则指从IO流中恢复改Java对象。
如果需要让某个对象支持序列化机制,则必须让它的类是可序列化的(Serializable)。为了让某个类的可序列化的,该类必须实现如下两个接口之一。
Serializable
Externalizable
Java的很多类已经实现了Serializable,该接口是一个标记接口,实现该接口无需实现任何方法,它只是表明该类的实例是可序列化的。
所有可能在网络上传输的对象的类都应该是可序列化的,否则程序将会出现异常,比如RMI(Remote Method Invoke 即远程方法调用,是JavaEE 的基础)过程中的参数和返回值;若有需要保存到磁盘里的对象的类都必须可以序列化,比如web应用中需要保存到HttpSesion或ServletContext属性的Java对象。、
因为序列化是RMI过程的参数和返回值都必须实现的机制,而RMI又是JavaEE技术的基础——所有的分布式应用常常需要夸平台,夸网络,所以要求所有传递的参数、返回值必须实现序列化。因此序列化机制是JavaEE平台的基础。通常建议,程序创建的每个JavaBean都都实现Serializble

你可能感兴趣的:(IO流序列化与反序列化)