本文的目的是介绍ObjectInputStream的详细情况,特别关注socket.getInputStream的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解Obj
本文的目的是介绍ObjectInputStream的详细情况,特别关注socket.getInputStream的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解ObjectInputStream的机会,同时也不会遗漏关于Jakartase_IO流_ — 序列化与ObjectInputStream、ObjectOutputStream(五)、Java FileInputStream ObjectInputStream到达文件EOF的结尾、Java IO框架总揽--ObjectInputStream& ObjectOutputStream源码解读、Java IO类库之ObjectInputStream和ObjectOutPutStream的知识。
本文目录一览:- ObjectInputStream(socket.getInputStream()); 不起作用(objectinputstream cannot be resolved)
- Jakartase_IO流_ — 序列化与ObjectInputStream、ObjectOutputStream(五)
- Java FileInputStream ObjectInputStream到达文件EOF的结尾
- Java IO框架总揽--ObjectInputStream& ObjectOutputStream源码解读
- Java IO类库之ObjectInputStream和ObjectOutPutStream
ObjectInputStream(socket.getInputStream()); 不起作用(objectinputstream cannot be resolved)
我正在编程一个类以与服务器进行通信,但是当它尝试在inputstream的帮助下构造ObjectInputStream时,程序将冻结。没有异常,程序仍在运行,但挂在试图构造ObjectInputstream的行中。
这是我的问题所在的方法的代码:
@Overridepublic void connect(String ip, int port) throws UnknownHostException, IOException { Socket socket = new Socket(ip, port); out = new ObjectOutputStream(socket.getOutputStream()); InputStream is = socket.getInputStream(); in = new ObjectInputStream(is);}
这是整个类的代码:
package Client;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;public class MessageStreamerImpl implements MessageStreamer { ObjectOutputStream out; ObjectInputStream in; public MessageStreamerImpl(String ip, int port) throws UnknownHostException, IOException{ connect(ip, port); } public MessageStreamerImpl(){ } @Override public void send(Object message) throws IOException { if(out == null) throw new IOException(); out.writeObject(message); out.flush(); } @Override public Object receive() throws IOException{ try { return in.readObject(); } catch (ClassNotFoundException e) { throw new IOException(); } } @Override public void connect(String ip, int port) throws UnknownHostException, IOException { Socket socket = new Socket(ip, port); out = new ObjectOutputStream(socket.getOutputStream()); InputStream is = socket.getInputStream(); in = new ObjectInputStream(is); }}
在查看Google时,我发现了这一点:http : //www.coderanch.com/t/232944/threads/java/Socket-
getInputStream-block。但是我仍然不知道如何解决该问题,因为我的ObjectOutputStream构造函数在ObjectInputStream的构造函数之前。
这是我的服务器代码,也许会有所帮助;)
package Server;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.util.ArrayList;public class Server { ArrayList<Socket> clients = new ArrayList<Socket>(); public Server(int port){ try { ServerSocket mySocket = new ServerSocket(port); waitForClients(mySocket); } catch (IOException e) { System.out.println("Unable to start."); e.printStackTrace(); } } private void waitForClients(ServerSocket mySocket) { while(true){ try { System.out.println("Ready to receive"); Socket client = mySocket.accept(); clients.add(client); System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); Thread t = new Thread(new ClientHandler(client)); t.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shareToAll(Object objectToSchare){ for(Socket client:clients){ ObjectOutputStream oos; try { oos = new ObjectOutputStream(client.getOutputStream()); oos.writeObject(objectToSchare); oos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class ClientHandler implements Runnable{ Socket clientSocket; public ClientHandler(Socket clientSocket){ this.clientSocket = clientSocket; } @Override public void run() { try { ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); while(true){ try { ois.readObject(); } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }catch(SocketException e){ System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); clients.remove(clientSocket); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
感谢您的帮助,我发现了问题。它是在服务器类上,看起来像这样:
package Server;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.util.ArrayList;public class Server { ArrayList<ObjectOutputStream> clientstreams = new ArrayList<ObjectOutputStream>(); public Server(int port){ try { ServerSocket mySocket = new ServerSocket(port); waitForClients(mySocket); } catch (IOException e) { System.out.println("Unable to start."); e.printStackTrace(); } } private void waitForClients(ServerSocket mySocket) { while(true){ try { System.out.println("Ready to receive"); Socket client = mySocket.accept(); clientstreams.add(new ObjectOutputStream(client.getOutputStream())); System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); Thread t = new Thread(new ClientHandler(client)); t.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shareToAll(Object objectToSchare){ for(ObjectOutputStream stream:clientstreams){ try { stream.writeObject(objectToSchare); stream.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class ClientHandler implements Runnable{ Socket clientSocket; public ClientHandler(Socket clientSocket){ this.clientSocket = clientSocket; } @Override public void run() { try { ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); while(true){ try { ois.readObject(); } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }catch(SocketException e){ System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); clientstreams.remove(clientSocket); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
您在方法waitForClients()上看到的更改最多,但是我也更改了ArrayList和shareToAll方法的概念。
答案1
小编典典ObjectInputStream构造函数从给定的InputStream读取数据。为了使它起作用, 必须
在构造后立即刷新ObjectOutputStream(以写入初始标头),然后再尝试打开ObjectInputStream。同样,如果您希望每个连接发送多个对象,则必须打开一次ObjectOutputStream并将其用于套接字的生命周期(例如您的shareToAll
方法)。
Jakartase_IO流_ — 序列化与ObjectInputStream、ObjectOutputStream(五)
一、前言
- 本小节会简要概括Java IO中的序列化以及涉及到的流,主要包括ObjectInputStream和ObjectOutputStream。
二、关键字
2.1 Serializable
2.1.1
作用:
- 如果你希望类能够序列化和反序列化,必须实现Serializable接口,Java Serializable接口(java.io.Serializable是类如果要序列化和反序列化的话必须实现的标记接口。
- Java对象序列化(写入)是使用ObjectOutputStream和反序列化(读取)是通过ObjectInputStream.
2.1.2
意义:
- Serializable是一个标记接口,意味着它不包含任何方法。因此,一个类实现Serializable不需要实现任何特定的方法。一个类实现Serializable接口是告诉Java这个类是用于对象序列化的。
2.1.3
demo:
import java.io.Serializable;
public static class Person implements Serializable {
public String name = null;
public int age = 0;
public transient double salary = 130000; //transient短暂的,表示该变量不序列化
}
2.2 ObjectInputStream
2.2.1
作用:
- ObjectInputStream能够让你从输入流中读取Java对象,
2.2.2
意义:
- 读取文件中的对象时,不需每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了。
2.2.3
demo:
ObjectInputStream input =
new ObjectInputStream(new
BufferedInputStream(new (FileInputStream("object.data")));
MyClass object = (MyClass) input.readObject(); //etc.
input.close();
- 注:你读取的对象必须是MyClass的一个实例,并且必须事先通过ObjectOutputStream序列化到"object.data"文件中
2.3 ObjectOutputStream
2.3.1
作用:
- ObjectOutputStream能够让你把对象写入到输出流中
2.3.2
意义:
- 若要把对象写入(序列化)到输出流中,而不需要每次写入一个字节。你可以把OutputStream包装到ObjectOutputStream中,然后就可以把对象写入到该输出流中了
2.3.3
demo:
OutputStream output = new FileOutputStream("data/data.bin");
try (ObjectOutputStream oos =
new ObjectOutputStream(output)) { //java7_try with resource
Person person = new Person();
person.name = "Call me Shonan!";
person.age = 18;
oos.writeObject(person);
}
-
注:
- (1)、第一个FileOutputStream实例不是在try-with-resources块中创建的。这意味着,try-with-resources块将不会自动关闭这个文件输出流实例。但是,当ObjectOutputStream被关闭时,它也会关闭它写入的OutputStream实例,因此当oos关闭时,fileoutputstream实例将被关闭,
- (2)、在你序列化和反序列化一个对象之前,该对象的类都必须实现了java.io.Serializable接口
三、附:
-
注意
1. static属性不参与序列化。 2. 对象中的某些属性如果不想被序列化,不能使用static,而是使用transient修饰。 3. 为了防止读和写的序列化ID不一致,一般指定一个固定的序列化ID。
- 据作者得知,对象序列化本身就是一个主题,于此我们不再深入讨论有关对象序列化的更深入的细节!感兴趣的、想深入学习序列化的小伙伴可以自行深入探索!
Java FileInputStream ObjectInputStream到达文件EOF的结尾
我试图使用readObject读取二进制文件中的行数,但得到IOException EOF。我这样做正确吗?
FileInputStream istream = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(istream);
/** calculate number of items **/
int line_count = 0;
while( (String)ois.readObject() != null){
line_count++;
}
Java IO框架总揽--ObjectInputStream& ObjectOutputStream源码解读
ObjectInputStream与ObjectOutputStream的作用是:对基本数据和对象进行序列化操作进行支持。其中ObjectInputStream对象提供对基本数据和对象对持久存储,当我们需要读取这些存储这些基本数据或对象时,可以创建文件输入流对应的ObjectInputStream,进而读取这些基本数据或对象。
序列化有关的基础知识:
1 需要序列化的类必须实现java.io.Serializable接口,否则会抛出NotSerializableException异常。
2 如果检测到反序列化的类的serialVersionUID和对象二进制流的serialVersionUID不同,则会抛出异常。
3 Java序列化会将一个类中包含的引用中的所有的成员变量保存下来,所以里面的引用类型也要实现java.io.Serializable的接口。
4 对于不用采用默认序列化或无需序列化的成员变量,可以添加transient关键字,并不是说添加了transient关键字就一定不能序列化。
5 每一个类可以实现readObject、writeObject等方法实现自己的序列化策略,即使是transient修饰的成员变量也可以手动调用ObjectOutputStream的write*等方法,将成员变量序列化。
ObjectOutputStream 有关方法
1 public ObjectOutputStream(OutputStream out) throws IOException {}
* 创建一个ObjectOutputStream去写入指定的OutputStream,此构造函数将序列化流头写入底层流,调用者需要立即刷新流,以确保用于接收ObjectInputStreams的构造函数在读取该头时不会阻塞。
2 protected ObjectOutputStream() throws IOException, SecurityException {}
* 为完全重新实现ObjectOutputStream的子类提供一种方法,使其不必分配仅由ObjectOutputStream的实现使用的私有数据
3 public void useProtocolVersion(int version) throws IOException {}
* 指定在编写流时使用的流协议版本
4 public final void writeObject(Object obj) throws IOException {}
* 将指定的对象写入ObjutoExtStudio流,对象的类、类的签名、类及其所有超类型的非瞬态和非静态字段的值都可以通过该方法写入,重写writeObject和readObject方法可以将默认的序列号重写,该对象引用的对象是通过传递方式编写的,以便ObjectInputStream可以重构等效的、完整的对象。
Java IO类库之ObjectInputStream和ObjectOutPutStream
一、ObjectOutputStream
1 - ObjectOuputStream介绍
ObjectOutputStream(对象字节输出流),用于将一个序列化对象写入到创建ObjectOutputStream时传入的底层字节输入流中,通过源码可知该类继承OutputStream的同时实现了ObjectOutput接口,而此接口继承了DataOut接口,因此ObjectOutputStream在具有DataOutputStream写入基础数据类型到底层字节流功能的同时也具有将对象、数组和字符串写入到底层字节输入流中的功能。
ObjectOutputStream与DataOutputStream的区别:
1)ObjectOutputStream是将一个对象的所有属性、还有类信息的额外信息写入到底层字节输出流中,而DataOutputStream一次写入的只是一个基础类型数据
2)读取时ObjectOutputStream一次只读取一个对象不关心每个对象属性的写入顺序,DataOutputStream需要严格按照写入顺序进行读取
2 - ObjectOutputSteam源码解析
1)常用成员方法
protected void annotateClass(Class<!--?--> cl); 子类可以实现此方法,从而允许在流中存储类数据。
protected void annotateProxyClass(Class<!--?--> cl); 子类可以实现此方法,从而在流中存储定制数据和动态代理类的描述符。
void close();//关闭当前流、释放所有与此流有关的资源。
void defaultWriteObject();//将表示当前类状态的属性写入到构造时传入的底层流out中。
protected void drain();//将ObjectOutputStream中的所有已缓冲数据写入到底层流中、注意:但是不flush底层流、
protected boolean enableReplaceObject(boolean enable);//允许流对流中的对象进行替换。
void flush();//刷新该流的缓冲、这里也会将底层流中的数据flush到底层流指定的目的地中。
ObjectOutputStream.PutField putFields();//获取用于缓冲写入流中的持久存储字段的对象。
protected Object replaceObject(Object obj);//在序列化期间,此方法允许 ObjectOutputStream 的受信任子类使用一个对象替代另一个对象。
void reset();//重置将丢弃已写入流中的所有对象的状态。
void write(byte[] buf);//写入一个 byte 数组。
void write(byte[] buf, int off, int len);//写入字节的子数组。
void write(int val);//写入一个字节。
void writeBoolean(boolean val);//写入一个 boolean 值。
void writeByte(int val);//写入一个 8 位字节。
void writeBytes(String str);//以字节序列形式写入一个 String。
void writeChar(int val);//写入一个 16 位的 char 值。
void writeChars(String str);//以 char 序列形式写入一个 String。
protected void writeClassDescriptor(ObjectStreamClass desc);//将指定的类描述符写入ObjectOutputStream。
void writeDouble(double val); //写入一个 64 位的 double 值。
void writeFields();//将已缓冲的字段写入流中。
void writeFloat(float val);//写入一个 32 位的 float 值。
void writeInt(int val);//写入一个 32 位的 int 值。
void writeLong(long val);//写入一个 64 位的 long 值。
void writeObject(Object obj);//将指定的对象写入 ObjectOutputStream。
protected void writeObjectOverride(Object obj); //子类用于重写默认 writeObject 方法的方法。
void writeShort(int val);//写入一个 16 位的 short 值。
protected void writeStreamHeader();//提供 writeStreamHeader 方法,这样子类可以将其自身的头部添加或预加到流中。
void writeUnshared(Object obj);//将“未共享”对象写入 ObjectOutputStream。
void writeUTF(String str);//以 UTF-8 修改版格式写入此 String 的基本数据。
二、ObjectInputStream
1 - ObjectInputStream介绍
ObjectInputStream是对象字节输入流,继承自InputStream,用于从底层字节输入流中读取一个序列化对象到程序中,与ObjectOutputStream功能相对应,实现了ObjectInput接口,而ObjectInput实现了DataInput接口,在实现DataInput接口定义的基础类型数据的基础上扩展了读取对象、数组和字符串的功能。它可以和FileInputStream和FileOutStream将使用ObjectOutputStream持久化的对象、数组和字符串读取到程序中,并还原状态,当然还可以用于在网络中传输对象数据。
2 - ObjectInputStream源码分析
1)构造方法
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
}
protected ObjectInputStream() throws IOException, SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
bin = null;
handles = null;
vlist = null;
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = true;
}
两个构造方法逻辑基本相同,不同点在于ObjectInputStream是创建一个全新的字节流,而ObjectInputStream(InputStream in)的部分属性基于绑定的字节输入流in
2)其他常用成员方法
int available(); //返回不受阻塞地读取的字节数
void close();//关闭输入流
void defaultReadObject();//从当前输入流读取当前类状态的属性(没有被static、transient修饰的字段)
protected boolean enabledResolveObject(boolean enable);//使流允许从该流读取的对象被替换
int read();//读取字节数据
int read(byte[] buf, int off, int len);//读入byte数组
boolean readBoolean();//读取一个boolean值
byte readByte();//读取一个8位字节
char readChar();//读取一个16位char值
...
String readUTF();//读取UTF-8格式的String
readFully(byte buf[])
readFully(byte buf[],int off,int len);//阻塞直至读取所有字节
ObjectInputStream.GetField readFields();//按名称从流中读取持久字段并使其可用
今天关于ObjectInputStream和socket.getInputStream的介绍到此结束,谢谢您的阅读,有关Jakartase_IO流_ — 序列化与ObjectInputStream、ObjectOutputStream(五)、Java FileInputStream ObjectInputStream到达文件EOF的结尾、Java IO框架总揽--ObjectInputStream& ObjectOutputStream源码解读、Java IO类库之ObjectInputStream和ObjectOutPutStream等更多相关知识的信息可以在本站进行查询。
本文标签: