在Java程序开发过程中我们发现并不能够让程序多次运行时获得上一次关闭程序前的运行结果——我们没有将运行的结果加以保存。这个时候我们就要找到Java操作读取数据的方法(以操作文件为例):Java中的输入/输出模型,I/O模型又称为I/O流。(以下简称I/O流)。
流按方向可以分为输入(input)和输出(output)2种。输入和输出是相对的,这里我们是站在程序的角度来看的,将程序的数据写到文件就是输出,从文件中读取数据就是输入。
按类型(大小)可以分为字节型(byte)和字符型(byte)2种,字符流对象类型为Reader和Writer,字节流对象的类型为InputStream和OutputStream。我们知道字符(char)的大小是字节(byte)的两倍,但是这不是说字符型的I/O流就要比字节型的适用范围更广。具体地说,字符型的I/O流只有在操作纯文本(TXT)文件的时候才适用,并且不包括word等文件;除了TXT文件之外,其他类型的文件在被计算机解析的时候都会当做字节码处理,也就是由二进制的1和0组成,此时文件的读取用字符类型I/O流就不合适。实际使用中我们要根据文件的类型(是否TXT)来选择所使用的I/O流类型。
按作用分类又可以分为节点流(如FileInputStream)和操作流(如ObjectInputStream)2种。节点是指流两端链接的可以是文件或者是其他的对象,节点流就是直接链接两个操作对象的流。而操作流不能连接两个操作对象,它必须依附与某种节点流而使用,它的功能是指定所需传送的数据的传送形式。
Java中,能够直接操作文件的常见有Properties类型的集合,Properties对象调用这个类型的.store(参数)方法 和load(参数)方法,参数位置放一个I/O流对象即可对文件进行存取操作。而实际使用中我们将各种类型的数据转换成Properties类型的数据会非常麻烦。这个时候我们就需要能够将数据已对象的形式进行存取的一种I/O流,也就是上文中讲的操作流。
此处详细讲一下操作流(ObjectOutputStream和ObjectInputStream)。
有一点需要注意的是,将对象写到文件时需要先让对象继承Serializable接口,该接口不需要重写任何方法,仅仅是作为该对象可被序列化的标识。若要使对象重的某个属性不可被序列化,需要再该属性前加上可选修饰符——transient关键字。以下为操作流的具体用法。
ObjectIOututStream oos = null; //定义一个操作流对象,名为oos
oos = new ObjectIOututStream(new FileIOutputStream("abc.Dos");
//初始化oos (此处应该捕获异常,篇幅有限,从略);
//构造方法中传入一个节点流对象;
//节点流中参数为String类型的文件路径
ois.writeObject(参数); //调用writeObject()方法,参数为已经实现了Serializable接口的对象
这样我们就完成了见对象存为未见的操作。
ObjectInputStream ois = null; //定义一个操作流对象,名为ois
ois = new ObjectInputStream(new FileInputStream("abc.Dos");
//初始化ois (此处应该捕获异常,篇幅有限,从略);
//构造方法中传入一个节点流对象;
//节点流中参数为String类型的文件路径
Object obj = ois.readObject(); //调用readObject()方法,返回Object类型的对象,按需可以强转
这样 就完成了从文件中读取对象的操作。
总之,我们要确定所要做的时确定输入还是输出,是字符流还是字节流,是那种类型,目的地或者数据源,然后按步骤调用方法完成数据的存取即可。