3

在我正在为大学工作的这个 Java 项目中,我有一种情况,我目前正在通过网络成功发送字符串

streamOut = ObjectOutputStream
streamIn = ObjectInputStream

streamOut.writeUTF(msgs.peek());

其中 msgs 是一个链接的阻塞队列,接收它

String in = streamIn.readUTF();

但是,我想使用 ObjectInputStream 和 ObjectOutputStream。我已经在构造函数中初始化了它们,并且在构造它之后刷新了 ObjectOutputStream,我在某个地方读到了你必须这样做。

我想同时发送字符串和另一种对象类型,通过网络将其称为gameWorld(此时不关心效率)..但是当我这样做时

streamOut.writeObject("mad cuz i'm bad");

Object in = streamIn.readObject(); 
if(in instanceof String) String inS = (String) in;

当我发送字符串时它没有收到任何东西......我的朋友正在做同一个项目,他只传递了一种类型的对象,这个对象的一个​​子类本质上是一个字符串,他的版本工作正常,但他在线程运行循环的每次迭代中都会创建一个新流。

我是否需要对流做一些事情来接收除了 Object 之外没有共同祖先的不同对象,我是否需要在运行循环的每次迭代中创建一个新流,或者我是否完全有其他东西丢失并且我提供的信息不足以说明问题所在?

4

3 回答 3

4

将字符串作为原始数据或作为对象写入流中存在显着差异。writeObject 写入的 String 实例最初作为 String 写入流中。未来的 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第一 t 第二t 第三

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 第一第二第三

结论:在 writeObject 的情况下,要流式传输额外的数据(此处为t),而在 writeUTF 的情况下,只有要流式传输的字符串数据。

更多信息:http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeUTF(java.lang.String)

于 2013-10-09T13:15:15.937 回答
0

如果要使用 readObject() 读取字符串,则必须使用 writeObject() 写入。

于 2013-10-09T11:19:34.123 回答
0

最重要的区别是,如果您使用 编写字符串writeUTF(),则整个字符串将始终作为 UTF 编码字符写入流中。但是,如果您使用writeObject(),则 String 的 Object 实例将写入流。所以如果你用 写同一个实例的多个字符串writeObject(),那么返回的相应字符串readObject()也将保证是同一个 Object 实例,而当你用 读取它们时readUTF(),它们将不是同一个 Object 实例:

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()),这可能会产生巨大的差异。

于 2021-03-12T06:37:19.580 回答