在我正在为大学工作的这个Java项目中,我遇到的情况是我正在使用
成功通过网络发送字符串streamOut = ObjectOutputStream
streamIn = ObjectInputStream
streamOut.writeUTF(msgs.peek());
其中msgs是一个链接的阻塞队列,用
接收它String in = streamIn.readUTF();
但是,我想使用ObjectInputStream和ObjectOutputStream。我已经在构造函数中初始化它们,并在构造它之后刷新ObjectOutputStream,我读到了你必须要做的地方。
我想发送两个字符串和另一个Object类型,通过网络称它为gameWorld(此时不关心效率)..但是当我这样做时
streamOut.writeObject("mad cuz i'm bad");
Object in = streamIn.readObject();
if(in instanceof String) String inS = (String) in;
当我发送字符串时,它没有选择任何东西......我的朋友正在处理同一个项目,他只传递一种类型的对象,这个对象的一个子类本质上是一个字符串和他的版本工作正常,但他在他的线程的运行循环的每次迭代中都创建了一个新流。
我是否需要对流做一些事情以接收不具有除Object之外的共同祖先的不同对象,我是否需要在运行循环的每次迭代中创建一个新流,或者是否只有完全相同的东西我失踪了,我提供的信息不足以说明错了什么?
答案 0 :(得分:4)
将String作为原始数据或Object写入流中之间存在显着差异。 writeObject编写的String实例最初以String形式写入流中。 Future writeObject()将对字符串的写入引用调用到流中。
例如
ByteArrayOutputStream baos1=new ByteArrayOutputStream();
oos1=new ObjectOutputStream(baos1);
baos2=new ByteArrayOutputStream();
ObjectOutputStream oos2=new ObjectOutputStream(baos2);
String testString="First";
oos1.writeObject(testString);
oos2.writeUTF(testString);
testString="Second";
oos1.writeObject(testString);
oos2.writeUTF(testString);
testString="Third";
oos1.writeObject(testString);
oos2.writeUTF(testString);
oos1.flush();
oos2.flush();
byte[] byteArray1=baos1.toByteArray();
byte[] byteArray2=baos2.toByteArray();
转储最后两个数组,你会得到如下结果:
writeObject 即byteArray1
二进制:-84 -19 0 5 116 0 5 70 105 114 115 116 116 0 6 83 101 99 111 110 100 116 0 5 84 104 105 114 100
ASCII:-T - t F
writeUTF 即byteArray2
二进制:-84 -19 0 5 119 22 0 5 70 105 114 115 116 0 6 83 101 99 111 110 100 0 5 84 104 105 114 100
ASCII:-T - w F r r s t e c o n d T h i r d
结论:如果writeObject需要流式传输额外的数据(此处为 t ),而在writeUTF的情况下,只有要传输的字符串数据。
更多信息:http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeUTF(java.lang.String)
答案 1 :(得分:0)
如果要使用readObject()读取字符串,则必须使用writeObject()编写它。
答案 2 :(得分:0)
最重要的区别是,如果你用 writeUTF()
写字符串,那么整个字符串将始终作为 UTF 编码字符写入流。但是,如果您使用 writeObject()
,则 String 的 Object 实例将写入流。所以如果你用writeObject()
写了同一个实例的多个Strings,那么readObject()
返回的对应Strings也会保证是同一个Object实例,而当你用readUTF()
读取它们的时候,它们将不是是同一个对象实例:
ByteArrayOutputStream bytes1 = new ByteArrayOutputStream();
ObjectOutputStream out1 = new ObjectOutputStream(bytes1);
ByteArrayOutputStream bytes2 = new ByteArrayOutputStream();
ObjectOutputStream out2 = new ObjectOutputStream(bytes2);
String writeString = "test";
out1.writeObject(writeString);
out1.writeObject(writeString);
out2.writeUTF(writeString);
out2.writeUTF(writeString);
out1.flush();
out2.flush();
ObjectInputStream in1 = new ObjectInputStream(new ByteArrayInputStream(bytes1.toByteArray()));
ObjectInputStream in2 = new ObjectInputStream(new ByteArrayInputStream(bytes2.toByteArray()));
String readString1 = (String) in1.readObject();
String readString2 = (String) in1.readObject();
System.out.println(readString1 == readString2);
readString1 = (String) in2.readUTF();
readString2 = (String) in2.readUTF();
System.out.println(readString1 == readString2);
打印:
true
false
这也会导致非常不同的流:使用 writeUTF()
我们得到一个长度为 18 的 byte[],其中包含两次 UTF 字符“test”。使用 writeObject()
我们得到一个长度为 16 的 byte[] ,它只包含一次 UTF 字符“test”,后跟一个表示字符串引用 ID 的整数。所以 writeObject()
通常会导致文件变小。如果将同一实例的大量字符串写入流(例如,通过调用 String.intern()
),这会产生巨大的差异。