簡體   English   中英

writeUTF(String s) 與 writeObject(String s)

[英]writeUTF(String s) vs writeObject(String s)

在我為大學工作的這個 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 之外沒有共同的祖先,我是否需要在運行循環的每次迭代中創建一個新的流,或者我是否完全有其他東西缺少並且我提供的信息不足以說明哪里出了問題?

將字符串作為原始數據或作為對象寫入流中存在顯着差異。 由 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的開始步驟牛逼小號的Econd 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 First S second T hird

結論:在 writeObject 的情況下,要流式傳輸額外的數據(此處為t ),而在 writeUTF 的情況下,只有要流式傳輸的字符串數據。

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

如果你想用 readObject() 讀取字符串,你必須用 writeObject() 寫它。

最重要的區別是,如果您使用writeUTF()編寫 String,那么整個 String 將始終作為 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() ),這可能會產生巨大的差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM