ObjectInputStream ObjectOutputStream

object|stream

ObjectOutputStream和ObjectInputStream

--ObjectOutputStream

ObjectInputStream 类恢复以前使用 ObjectOutputStream 类序列化后的基本类型数据和对象。

ObjectOutputStream 和 ObjectInputStream 分别利用 FileOutputStream 和 FileInputStream 能支持应用程序实现对象图象的稳定存储。

ObjectInputStream 可用于恢复以前序列化过的对象。另外其它一些情况也使用此类,诸如使用一个 Socket 在主机间传递对象时,

或在远程通讯系统中为实现参数和参变量的通讯而进行对象传递时。

ObjectInputStream 保证从流中创建的图象中的所有对象的类型与 Java 虚拟机中出现的类匹配。使用标准机制按需装载相应类。

只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流中读取。使用 readObject 方法从该流中

读取一个对象。 Java 的安全造型应该用于获取期望类型。在 Java 中, 串和数组都是对象且可当作是序列化过程中的对象。

读取时,它们需要转换为所需类型。

另外基类型也可使用 DataInput 中的正确方法从该流中读取。

对象的缺省逆序列化机制将每个域的内容恢复为它被写入时的值和类型。逆序列化过程中忽略申明为暂时的或静态的域。

对其它对象的引用促使那些对象必须从流中读取。使用引用共享机制正确地恢复对象的图象。逆序列化时总是分配新对象,

防止重写已存在的对象。

读取一个对象同运行一个新对象的构造子类似。为该对象分配的内存初始化为空(NULL)。为非序列化类调用无参构造子,

然后将序列化类的域从该流中恢复,恢复从最接近 java.lang.object 的序列化对象开始,到指定对象结束。

例如读取在示例中写入 ObjectOutputStream 中的流:

 FileInputStream istream = new FileInputStream("t.tmp"); ObjectInputStream p = new ObjectInputStream(istream); int i = p.readInt(); String today = (String)p.readObject(); Date date = (Date)p.readObject(); istream.close(); 类通过实现 java.io.Serializable 或 java.io.Externalizable 接口来控制它们的序列化。

实现序列化接口可以使对象能保存和恢复它的完整状态,可以使类在写入流和从流中读取的期间内进行改进。

它自动地遍历对象间的引用,保存和恢复完整图象。在序列化和逆序列化处理过程中需要特定句柄的可序列化类,

必须实现如下这两个方法:

 private void writeObject(java.io.ObjectOutputStream stream)     throws IOException; private void readObject(java.io.ObjectInputStream stream)     throws IOException, ClassNotFoundException;  利用 writeObjectmethod 方法将一个特殊类的对象的状态写入某流后,相应的 readObject 方法将负责读取和恢复这些数据。

此方法不必关心状态是属于它的父类还是子类。 从 ObjectInputStream 读取数据恢复单个域的状态,并将之赋给该对象的恰当域。

使用 DataInput 方法读取基本数据类型。

序列化操作对没有实现 java.io.Serializable 接口的对象,不读取或分配它的域值。非序列化对象的子类可以是序列化的。

在这种情况下,非序列化类必须有一个无参构造子,使它的域能使用此构造子完成初始化。 在此情况下,

子类负责保存和恢复非序列化类的状态。通常情况父类的域是可存储的(公有的、包或保护的),

或存在用于恢复它的状态的可使用的获取或设置方法。

ObjectInputStream 能获取逆序列化一个对象期间出现的任一异常,一旦出现异常,则放弃读过程。

实现外部接口可以使对象完全控制此对象序列化形式的内容和格式。

调用外部接口的方法:writeExternal 和 readExternal 保存和恢复对象状态。当一个类实现了这些方法时,

它们就能使用 ObjectOutput 和 ObjectInput 方法的所有方法写入或读取它们自己的状态。对象负责管理它出现的相应版本。

ObjectOutputStream

public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants 类 ObjectOutputStream 将 Java 对象中的基本数据类型和图元写入到一个 OutputStream 对象中。可使用 ObjectInputStream 读取这些对象。

另外使用此流对应的文件能存储这些对象。如果该流是一个网络通讯流,则在另一台主机或另一个处理机上可重建这些对象。

只有支持 java.io.Serializable 接口的对象才能被写入该流。对每个可序列化的对象进行编码,包括相应类的名称和标记,

对象的属性和数组值,以及初始化对象时引用的任何其它对象等。

使用 writeObject 将一个对象写入该流。任一对象,包括串和数组,均采用 writeObject 方法被写入。

也能将多个对象或基类型对象写入此流。反过来,必须以这些对象被写入的相同类型和相同顺序,

从相应的 ObjectInputstream 流中读回这些对象。

基类型也可使用 DataOutput 中的正确方法写入此流。串对象也可使用 writeUTF 方法写入。

一个对象的缺省序列化机制将写入对象的类,类标记和所有的非暂时的和非静态的属性值。

其它对象(除暂时的或静态的属性)的引用也将促使以上这些对象被写入。 使用共享机制,对单一对象的多次引用进行编码,

以至对象的图元能被存储为与它原来写入时有相同的形状。

例如写入一个对象,此对象能从 ObjectInputStream 中读出:

 FileOutputStream ostream = new FileOutputStream("t.tmp"); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeInt(12345); p.writeObject("Today"); p.writeObject(new Date()); p.flush(); ostream.close(); 在序列化处理过程中需要特定句柄的类,必须使用如下这些恰当的标记实现特定的方法:

 private void readObject(java.io.ObjectInputStream stream)     throws IOException, ClassNotFoundException;  private void writeObject(java.io.ObjectOutputStream stream)     throws IOException writeObject 方法负责写特定类的对象的状态,以使相应的 readObject 方法能存储它。

此方法不必关心写入对象的父类或子类的状态。使用 writeObject 方法或基本类型支持的 DataOutput

方法将每个域的状态保存到 ObjectOutputStream 中。

序列化操作不能输出没有实现 java.io.Serializable 接口的任一对象的域。非序列化对象的子类可以是序列化的。

在这种情况下,非序列化类必须有一个无参构造子,使它的域能被初始化。 在此情况下,子类负责保存和恢复非序列化类的状态。

通常情况父类的域是可存储的(公有的、包或保护的),或存在用于恢复它的状态的可使用的获取或设置方法。

实现抛出 NotSerializableException 异常的 writeObject 和 readObject 方法能阻止一个对象的序列化。

ObjectOutputStream 将获取这个异常,并放弃这个序列化过程。实现外部接口可以使对象完全控制此对象序列化形式的内容和格式。

调用外部接口的方法:writeExternal 和 readExternal 保存和恢复对象状态。当一个类实现了这些方法时,

它们就能使用 ObjectOutput 和 ObjectInput 方法的所有方法写入或读取它们自己的状态。对象负责管理它出现的相应版本。

import java.io.*;import java.util.*;

public class Logon implements Serializable {

       private Date date = new Date();       private String username;       private transient String password;

       Logon(String name, String pwd) {              username = name;              password = pwd;       }

       public String toString() {              String pwd = (password == null) ? "(n/a)" : password;              return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;       }

       public static void main(String[] args) throws IOException, ClassNotFoundException {              Logon a = new Logon("Morgan", "morgan83");              System.out.println( "logon a = " + a);              ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));              o.writeObject(a);              o.close();

              int seconds = 5;              long t = System.currentTimeMillis() + seconds * 1000;              while(System.currentTimeMillis() < t) ;

              ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));              System.out.println( "Recovering object at " + new Date());              a = (Logon)in.readObject();              System.out.println("logon a = " + a);        }} 

类Logon是一个记录登录信息的类,包括用户名和密码。首先它实现了接口Serializable,这就标志着它可以被序列化。

之后再main方法里ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));

新建一个对象输出流包装一个文件流,表示对象序列化的目的地是文件Logon.out。然后用方法writeObject开始写入。

想要还原的时候也很简单ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));

新建一个对象输入流以文件流Logon.out为参数,之后调用readObject方法就可以了。

时间: 2024-09-08 09:52:23

ObjectInputStream ObjectOutputStream的相关文章

java io学习(四) ObjectInputStream 和 ObjectOutputStream

本章,我们学习ObjectInputStream 和 ObjectOutputStream ObjectInputStream 和 ObjectOutputStream 介绍 ObjectInputStream 和 ObjectOutputStream 的作用是,对基本数据和对象进行序列化操作支持. 创建"文件输出流"对应的ObjectOutputStream对象,该ObjectOutputStream对象能提供对"基本数据或对象"的持久存储:当我们需要读取这些存储

java io系列05之 ObjectInputStream 和 ObjectOutputStream

本章,我们学习ObjectInputStream 和 ObjectOutputStream ObjectInputStream 和 ObjectOutputStream 介绍 ObjectInputStream 和 ObjectOutputStream 的作用是,对基本数据和对象进行序列化操作支持.创 建"文件输出流"对应的ObjectOutputStream对象,该ObjectOutputStream对象能提供对"基本数据或对象"的持久存储: 当我们需要读取这些存

存取程序状态的几种方法——Java I/O应用杂谈

程序 jungleford如是说     已经有一个多月没有搭理blog了,原因很多,譬如实验室的项目正在收工,巨忙:譬如找工作及其相关的事情:而且二月份大部分时间是陪老爹老妈,家里拨号的速度可想而知--但主要还是没有找到一个合适的topic,或者说这段时间懒了(临毕业前期综合症),净在看<汉武大帝>和历史方面的书,还有其它乱七八糟的闲书,就是没有认真地玩Java,哈哈!现在工作差不多落实了,好在不算太烂,小资青年jungleford的生活又开始步入正轨了!以上是新年里的一些废话.    今天

关于Java对象序列化您不知道的5件事

数年前,当和一个软件团队一起用 Java 语言编写一个应用程序时,我体会 到比一般程序员多知道一点关于 Java 对象序列化的知识所带来的好处. 大约一年前,一个负责管理应用程序所有用户设置的开发人员,决定将用户 设置存储在一个 Hashtable 中,然后将这个 Hashtable 序列化到磁盘,以便持 久化.当用户更改设置时,便重新将 Hashtable 写到磁盘. 这是一个优雅的.开放式的设置系统,但是,当团队决定从 Hashtable 迁移 到 Java Collections 库中的

分布式缓存技术redis学习系列----深入理解Spring Redis的使用

关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么优秀的一个框架. Spring-data-redis为spring-data模块中对redis的支持部分,简称为"SDR",提供了基于jedis客户端API的高度封装以及与spring容器的整合,事实上jedis客户端已经足够简单和轻量级,而spring-data-redis反而具有&qu

Java序列化与反序列化

1.什么是序列化?为什么要序列化? Java 序列化就是指将对象转换为字节序列的过程,而反序列化则是只将字节序列转换成目标对象的过程. 我们都知道,在进行浏览器访问的时候,我们看到的文本.图片.音频.视频等都是通过二进制序列进行传输的,那么如果我们需要将Java对象进行传输的时候,是不是也应该先将对象进行序列化?答案是肯定的,我们需要先将Java对象进行序列化,然后通过网络,IO进行传输,当到达目的地之后,再进行反序列化获取到我们想要的对象,最后完成通信. 2.如何实现序列化 2.1.使用到JD

学好Java入门的几个阶段,这样走你会学的更好

自己学Java的时候总是迷茫的,然后每个人的学习方式因为外界的影响,越来越没有明确的目标.比如什么多读书读好书,简直就是废话有木有. 同样的,很多人认为学习Java之前,需要先学习好c语言,但我个人认为,学了C语言自然好,但是尽管没有学习c语言,我们一样可以学好Java.毕竟Java是面向对象,c语言是面向过程的.除了部分语法上的雷同之外,其他的可以忽略. 下面,根据自身的学习经验,以及大佬们的学习方式,总结了一下流程,供新人参考学习. 第一阶段: 1.首先要掌握的一定是Java的语法,这是基础

Spark踩坑记:共享变量

前言 前面总结的几篇spark踩坑博文中,我总结了自己在使用spark过程当中踩过的一些坑和经验.我们知道Spark是多机器集群部署的,分为Driver/Master/Worker,Master负责资源调度,Worker是不同的运算节点,由Master统一调度. 而Driver是我们提交Spark程序的节点,并且所有的reduce类型的操作都会汇总到Driver节点进行整合.节点之间会将map/reduce等操作函数传递一个独立副本到每一个节点,这些变量也会复制到每台机器上,而节点之间的运算是相

java教程之对象序列化使用基础示例详解_java

这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新"装配".像RMI.Socket.JMS.EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳.  Java对象序列化机制一般来讲有两种用途: Java的JavaBeans: Bean的状态信息通常是在设计时配置的,Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息,这需要将对象的状态保存到文件中,而后能