通过java套接字通报工具
副标题#e#
利用JavaTM长途要领挪用(RMI),可以很利便地开拓漫衍式的基于工具的应用措施。RMI的简朴性,是由网络通信的用度作为价钱的。底层的套接字可以用来开拓客户/处事器系统,可是由于大大都Java I/O类和工具不太容易匹配,如何通过套接字通报完成的工具呢?工具序列化是一个答允您以比特流方法读/写完成工具的机制。
将底层的套接字和工具序列化团结在一起,您将获得一个强大的、高效的、可替代RMI的机制,通过套接字来通报工具还能降服利用RMI的高用度的问题。
工具序列化概述
工具序列化机制对付需要将工具的状态生存到文件中,尔后可以或许通过读入工具状态来从头结构工具,规复措施状态,可能利用套接字在网络上传送工具的措施来说,是很有用的。通过让类实现java.io.Serializable 接口可以将类序列化。这个接口是一个制造者(marker)接口。也就是说,对付要实现它的类来说,该接口不需要实现任何要领。它主要用来通知Java虚拟机(JVM),需要将一个工具序列化。
将工具读出可能写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。ObjectOutputStream 提供用来将工具写入输出流的writeObject要领, ObjectInputStream提供从输入流中读出工具的readObject要领。留意利用这些要领的工具必需被序列化,这很是重要。也就是说,这些类必需实现Serializable接口。
序列化已经存在的类
相识了工具序列化的基本常识之后,我们来看看如何对流读/写工具或现有的已序列化类实例。要将一个工具写入输出流,先成立一个输出流,然后利用writeObject工具生存到文件中。
——————————————————————————–
留意: Date类是可序列化的。换句话说,它实现 Serializable接口。
——————————————————————————–
例程 1: SaveDate.java
import java.io.*;
读入工具,然后从头结构它的状态都很容易。例程2中的代码向您展示了如何读一个已经序列化的工具而且打印它的信息。
import java.util.Date;
public class SaveDate {
public static void main(String argv[]) throws Exception {
FileOutputStream fos = new FileOutputStream("date.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Date date = new Date();
oos.writeObject(date);
oos.flush();
oos.close();
fos.close();
}
}
例程 2: ReadDate.java
import java.io.*;
import java.util.Date;
public class ReadDate {
public static void main(String argv[]) throws Exception {
FileInputStream fis = new FileInputStream("date.out");
ObjectInputStream ois = new ObjectInputStream(fis);
Date date = (Date) ois.readObject();
System.out.println("The date is: "+date);
ois.close();
fis.close();
}
}
#p#副标题#e#
在上面的例子中我们利用了Date类的一个实例,这是一个现成的已序列化的Java类。也许您会问这样的问题:是不是所有现成的Java类都是可序列化的?谜底是否认的。这不只因为这样做没须要,并且将某些类序列化是毫无意义的。利用JDK中的serialver东西,可以判定一个类是不是可序列化的。您可以在呼吁行模式下利用如下呼吁:
c:\> serialver java.util.Date
java.util.Date: static final long serialVersionUID = 7523967970034938905L;
(这个例子测试Date类是不是可序列化。输出功效暗示Date类是可序列化的,而且打印出了这个类的版本独一标识符。)
可能,您也可以利用如下呼吁启动图形界面下的serialver东西:
c:\> serialver -show
这个呼吁将弹出一个如图1所示的窗口,在这个窗口中写入您想查抄的类的名字(包罗路径)。图1显示的功效暗示 Date类是可序列化的。
图 1: Date是个可序列化的类
再说一次,不是所有的Java类都是可序列化的。举个例子,图2表白Socket类是不行序列化的。
图2: Socket是个不行序列化的类
序列化用户本身的类
此刻,让我们看看如何序列化用户本身写的类。在这个例子中,我们将成立一个用户类UserInfo,见例程3。为了让它可序列化,UserInfo类实现了Serializable接口。
例程 3: UserInfo.java
import java.io.*;
import java.util.*;
public class UserInfo implements Serializable {
String name = null;
public UserInfo(String name) {
this.name = name;
}
public void printInfo() {
System.out.println("The name is: "+name);
}
}
#p#分页标题#e#
下一步就是成立一个能建设UserInfo类实例的类,然后将工具写入输出流中,如例程4。本例中的输出流是一个名为"name.out"的文件。要留意的是,例程4 中的writeObject要领可以被挪用任意多次,将任意多个工具写入输出流。
例程 4: SaveInfo.java
import java.io.*;
import java.util.Date;
public class SaveInfo {
public static void main(String argv[]) throws Exception {
FileOutputStream fos = new FileOutputStream("name.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// create two objects
UserInfo user1 = new UserInfo("Java Duke");
UserInfo user2 = new UserInfo("Java Blue");
// write the objects to the output stream
oos.writeObject(user1);
oos.writeObject(user2);
oos.flush();
oos.close();
fos.close();
}
}
最后,我们写一个将已经生存的工具读入的类,而且挪用一个如例程5所示的要领。和writeObject 一样,readObject要领能被挪用任意多次,从输入流中读入任意多个工具。
例程 5: ReadInfo.java
import java.io.*;
import java.util.Date;
public class ReadInfo {
public static void main(String argv[]) throws Exception {
FileInputStream fis = new FileInputStream("name.out");
ObjectInputStream ois = new ObjectInputStream(fis);
// read the objects from the input stream (the file name.out)
UserInfo user1 = (UserInfo) ois.readObject();
UserInfo user2 = (UserInfo) ois.readObject();
// invoke a method on the constructed object
user1.printInfo();
user2.printInfo();
ois.close();
fis.close();
}
}
要测试这个例子,请编译如下源文件:UserInfo.java, SaveInfo.java, 和 ReadInfo.java。运行 SaveInfo,然后运行ReadInfo,将看到输出功效