科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道通过套接字传递对象

通过套接字传递对象

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

通过套接字传递对象

作者: javazh_cn 来源:赛迪网技术社区 2007年11月30日

关键字: 传递对象 套接字

  • 评论
  • 分享微博
  • 分享邮件
使用JavaTM远程方法调用(RMI),可以很方便地开发分布式的基于对象的应用程序。RMI的简单性,是由网络通信的费用作为代价的。底层的套接字可以用来开发客户/服务器系统,但是由于大多数Java I/O类和对象不太容易匹配,如何通过套接字传递完成的对象呢?对象序列化是一个允许您以比特流方式读/写完成对象的机制。 -u- !q8=o  
7 y8Dm  
将底层的套接字和对象序列化结合在一起,您将得到一个强大的、高效的、可替代RMI的机制,通过套接字来传递对象还能克服使用RMI的高费用的问题。 %61x.LNTn%  
A\OEIqiM  
;D+:2V  
简单概述对象序列化 d@_6$fj+  
介绍如何应用对象序列化 'aES(\*T  
解释如何应用已经存在的对象与用户对象 ,2D{kQd~'  
介绍如何通过套接字传递对象 eg~|cH  
提供多线程的服务器例子 <$S+gIE[  
提供一个基于对象的实现daytime协议的例子 p:h"]  
最后,简单比较了RMI和有对象序列化的套接字。 eYIUj"ww  
:f $ckt  
对象序列化概述 G\VBe1  
对象序列化机制对于需要将对象的状态保存到文件中,而后能够通过读入对象状态来重新构造对象,恢复程序状态,或者使用套接字在网络上传送对象的程序来说,是很有用的。通过让类实现java.io.Serializable 接口可以将类序列化。这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。 J!UHatQ&  
XtTmh0B+  
将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。ObjectOutputStream 提供用来将对象写入输出流的writeObject方法, ObjectInputStream提供从输入流中读出对象的readObject方法。注意使用这些方法的对象必须被序列化,这非常重要。也就是说,这些类必须实现Serializable接口。 aFWH*d  
0i>3${PNE  
序列化已经存在的类 CyE2NoN6B  
了解了对象序列化的基础知识之后,我们来看看如何对流读/写对象或现有的已序列化类实例。要将一个对象写入输出流,先建立一个输出流,然后使用writeObject对象保存到文件中。 HycA"sln  
G.Elb  
-------------------------------------------------------------------------------- b >D9zN  
注意: Date类是可序列化的。换句话说,它实现 Serializable接口。 4^`nDT3Y"  
-------------------------------------------------------------------------------- ; I;bs1g  
) s %N  
例程 1: SaveDate.java ;)+h6ZX=  
>Ov&;L5  
import java.io.*; ;2IW6|rla  
import java.util.Date; ~ 2{rLN  
%bQ:M|^1  
public class SaveDate { !F^EC=_E  
}Gvz  
public static void main(String argv[]) throws Exception { NH*SAY[69  
FileOutputStream fos = new FileOutputStream("date.out"); NJ)B bOK  
ObjectOutputStream oos = new ObjectOutputStream(fos); 1.xkm<=32l  
Date date = new Date(); #bGiG"Jb0  
oos.writeObject(date); K9kB*LZIhZ  
oos.flush(); YDqO@6c8  
oos.close(); %rRCqNoYy  
fos.close(); wE'w6Sfv5  
} # ^? .s7  
} IoXmbZ  
SBhc?^B@?  
读入对象,然后重新构造它的状态都很容易。例程2中的代码向您展示了如何读一个已经序列化的对象并且打印它的信息。 uv"d*#^  
V[ (KO1  
q<1 K  
例程 2: ReadDate.java >:y6AQI>  
Ar'HZ)rE{  
import java.io.*; WzYQs6An0  
import java.util.Date; 1{Yc2M>\>  
_BsR%0l~  
public class ReadDate {  Q'H6B9G  
S G%iA  
public static void main(String argv[]) throws Exception { f\Q0H$c0^  
FileInputStream fis = new FileInputStream("date.out"); D"]?6't(o  
ObjectInputStream ois = new ObjectInputStream(fis); 1EgwS!  
Date date = (Date) ois.readObject(); 6u`:f</  
System.out.println("The date is: "+date);  }+A>)NSd  
ois.close(); i h o4   
fis.close(); >o|]H> k  
} AT<p|^2(  
} 1* cri  
lm?h& K  
在上面的例子中我们使用了Date类的一个实例,这是一个现成的已序列化的Java类。也许您会问这样的问题:是不是所有现成的Java类都是可序列化的?答案是否定的。这不仅因为这样做没必要,而且将某些类序列化是毫无意义的。使用JDK中的serialver工具,可以判断一个类是不是可序列化的。您可以在命令行模式下使用如下命令: <-E.mT,  
p"&c 5s`A  
c:> serialver java.util.Date )Y ' {Kd?  
java.util.Date: static final long serialVersionUID = 7523967970034938905L; h E:eqy  
# 7-"#Exl0  
(这个例子测试Date类是不是可序列化。输出结果表示Date类是可序列化的,并且打印出了这个类的版本唯一标识符。) m, m"v  
t\ OE*6u  
或者,您也可以使用如下命令启动图形界面下的serialver工具: pQ< f{4  
\f'(k4y)#  
c:> serialver -show vPxiY2b  
\:{Q{$xUS  
这个命令将弹出一个如图1所示的窗口,在这个窗口中写入您想检查的类的名字(包括路径)。结果表示 Date类是可序列化的。 'P"@6C y  
WAbC4}s&N  
` QaMJR*  
再说一次,不是所有的Java类都是可序列化的。 j%KZcR2  
5 mNFVO  
序列化用户自己的类 \IofXhe6  
现在,让我们看看如何序列化用户自己写的类。在这个例子中,我们将建立一个用户类UserInfo,见例程3。为了让它可序列化,UserInfo类实现了Serializable接口。 3 5#@r  
0gAnQpH  
例程 3: UserInfo.java [i/3CW  
ISPUq8wrk  
import java.io.*; iq8_{Jq&  
import java.util.*; dw]J6K~+  
UD%buv=\d  
public class UserInfo implements Serializable { 7AY}R}>  
String name = null; ?4^"?f ;  
BG6/Uo=  
public UserInfo(String name) { 7}BRI>:D!'  
this.name = name; (<I.M>  
} WaeZ(  
ER&q-J[8  
public void printInfo() { aTIF?:pD4u  
System.out.println("The name is: "+name); 85q?].,Al  
} )`5[ZEp<p  
} {x%|=uD  
Dc3]>.=2  
下一步就是建立一个能创建UserInfo类实例的类,然后将对象写入输出流中,如例程4。本例中的输出流是一个名为"name.out"的文件。要注意的是,例程4 中的writeObject方法可以被调用任意多次,将任意多个对象写入输出流。 "QS3sQ5EG  
OsZq ,@`  
例程 4: SaveInfo.java wZ)&$$ut<L  
NoH| j\  
import java.io.*; nKP]t_1  
import java.util.Date; /|/_!8XY  
^W"BT,G  
public class SaveInfo { 2T^yp^N k  
;j|d0,  
public static void main(String argv[]) throws Exception { <P)7^lwx  
FileOutputStream fos = new FileOutputStream("name.out"); .MrtF7{s  
ObjectOutputStream oos = new ObjectOutputStream(fos); >)q[*]2*  
// create two objects wt J2J@iP  
UserInfo user1 = new UserInfo("Java Duke"); 9oHlyo%wk  
UserInfo user2 = new UserInfo("Java Blue"); xk:*7W@!  
// write the objects to the output stream {9x *;bAt'  
oos.writeObject(user1); CK0v.3G  
oos.writeObject(user2); @+p m#0  
oos.flush(); 5EIOMR%S  
oos.close(); ]j|'v2s!Bc  
fos.close();  W}}[  
} +q{ h~fp]c  
}  rc[6]<2  
std4_ZZuv  
最后,我们写一个将已经保存的对象读入的类,并且调用一个如例程5所示的方法。和writeObject 一样,readObject方法能被调用任意多次,从输入流中读入任意多个对象。 yvG3rdX|  
[S|DNM  
例程 5: ReadInfo.java wcED u  
J|k+*zF6`  
import java.io.*; &"FA}HbX+  
import java.util.Date; r=W5KTCF  
{@M[1!^Ip  
public class ReadInfo { jXN7>dwO  
sVxd< _  
public static void main(String argv[]) throws Exception { MwmynN|Y  
FileInputStream fis = new FileInputStream("name.out"); ?I>>S(]  
ObjectInputStream ois = new ObjectInputStream(fis); {v%4782GYm  
// read the objects from the input stream (the file name.out) 7uXmmT 0  
UserInfo user1 = (UserInfo) ois.readObject(); /A)uZ)  
UserInfo user2 = (UserInfo) ois.readObject(); 64S+B/J  
// invoke a method on the constructed object oKX2yU#00s  
user1.printInfo(); \ ze376!$  
user2.printInfo(); ;t# ai.`p  
ois.close(); %>OW G011  
fis.close(); 1.vN/GJ)  
} LzD%_5Uu  
} ,:WB7ajl  
 k_CEe_{  
要测试这个例子,请编译如下源文件:UserInfo.java, SaveInfo.java, 和 ReadInfo.java。运行 SaveInfo,然后运行ReadInfo,将看到类似下面的输出结果: Z]dY/SMyqs  
8>2F9-\Tt  
The name is: Java Duke H}Y_,[-k  
The name is: Java Blue
查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章