代码之家  ›  专栏  ›  技术社区  ›  boris dzhelali

writeUTF(字符串s)与writeObject(字符串s

  •  3
  • boris dzhelali  · 技术社区  · 11 年前

    在我为大学工作的这个Java项目中,我遇到了一种情况,即我目前正在使用

    streamOut = ObjectOutputStream
    streamIn = ObjectInputStream
    
    streamOut.writeUTF(msgs.peek());
    

    其中msgs是一个链接的阻塞队列,使用

    String in = streamIn.readUTF();
    

    但是,我希望使用ObjectInputStream和ObjectOutputStream。我已经在构造函数中初始化了它们,并在构造完ObjectOutputStream后刷新它,我在某些地方读到了必须这样做的内容。

    我想通过网络发送Strings和另一种Object类型,称之为gameWorld(此时不关心效率)。。但是当我这样做的时候

    streamOut.writeObject("mad cuz i'm bad");
    
    Object in = streamIn.readObject(); 
    if(in instanceof String) String inS = (String) in;
    

    当我发送字符串时,它不会拾取任何东西。。。我的朋友正在做同一个项目,他只传递了一种类型的对象,这个对象的一个子类本质上是一个字符串,他的版本运行得很好,但他在线程的运行循环的每一次迭代中都会生成一个新的流。

    我需要对流做些什么来接收除了Object之外没有共同祖先的不同对象吗?我需要在运行循环的每次迭代中制作一个新的流吗?还是我完全缺少了其他东西,并且我提供的信息不足以说明问题所在?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Prakash Bhagat    11 年前

    将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 0 6 83 101 99 111 110 100 116 0 5 84 104 105 114 100
    腹水:-T- 财务报表 S e c o n d公司 时间

    写入UTF 即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
    腹水:-T- w F i r s t s e c o n d时间

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

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

        2
  •  0
  •   user207421    11 年前

    如果你想用readObject()读取字符串,你必须用writeObject()来写。

        3
  •  0
  •   Balder    4 年前

    最重要的区别是,如果使用 writeUTF() ,则整个字符串将始终作为UTF编码的字符写入流中。但如果你使用 writeObject() ,则将String的Object实例写入流中。因此,如果您使用 写入对象() ,然后由返回的相应字符串 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
    

    这也导致了非常不同的流: 写入UTF() 我们得到一个长度为18的字节[],其中包括两次UTF字符“test”。具有 写入对象() 我们得到一个长度为16的字节[],其中只包含一次UTF字符“test”,后跟一个表示String的引用id的整数。所以 写入对象() 通常会导致文件大小变小。如果同一实例的大量字符串被写入流(例如,通过调用 String.intern() ).