2016-02-13 47 views
0

我正在寫一個java程序,通過套接字發送一個對象轉換爲字節數組。客戶端必須讀取所有字節並將其翻譯回Java對象。然而,我的程序卡在循環內的read(),我讀取所有字節,直到找到-1。如何在Java中發送對象時停止從BufferedReader讀取數據?

我讀過文檔,它說read()方法在到達流末尾時返回-1,但這不起作用。

繼承人我的代碼:發送對象 方法:

Socket socket; 
BufferedReader input; 
DataOutputStream output; 
boolean connectionOpen; //Just for you to know the types of the attributes of my class 
public void sendResponse(Object obj) throws IOException{ 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ObjectOutput out = null; 
    try { 
     out = new ObjectOutputStream(bos); 
     out.writeObject(obj); 
     byte[] yourBytes = bos.toByteArray(); 


     output.write(yourBytes); 

    } finally { 
     try { 
     if (out != null) { 
      out.close(); 
     } 
     } catch (IOException ex) { 
     // ignore close exception 
     } 
     try { 
     bos.close(); 
     } catch (IOException ex) { 
     // ignore close exception 
     } 
    } 


}  

方法讀取的字節數。 (這是我的代碼卡住的地方)

public Email getMail(int id) throws Exception{ 
    byte[] bytes = new byte[50000]; 
    Email result; 
    try{ 
     this.outToServer.writeBytes("MAIL "+id+"\n"); 
     String response = inFromServer.readLine(); 
     String[] data = response.split(" "); 
     int code = Integer.parseInt(data[0]); 
     if(code==500){ 
      throw new Exception("Error en servidor Pop4. Servidor respondio: "+response); 
     } 
     int current = inFromServer.read(); 
       int i = 0; 

     while(current!=-1){ 

      bytes[i]=(byte) current; 
      i++; 
      current= inFromServer.read(); 
     } 
     //Convertimos el arreglo de bytes a un objeto Email 
     ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 
     ObjectInput in = null; 
     try { 
      in = new ObjectInputStream(bis); 
      result = (Email) in.readObject(); 

     } finally { 
      try { 
      bis.close(); 
      } catch (IOException ex) { 
      // ignore close exception 
      } 
      try { 
      if (in != null) { 
       in.close(); 
      } 
      } catch (IOException ex) { 
      // ignore close exception 
       ex.printStackTrace(); 
      } 
     }    
    } 

    catch(Exception e){ 
      throw e; 
    } 
    return result; 


} 

回答

1

該文檔非常正確,InputStream.read()由於到達流尾而無法傳輸任何字節時返回-1。然而,你所提供的內容並沒有給我任何理由認爲條件會得到滿足。

流結束對應於一個條件,在該條件中可以確保從流中不會收到更多的字節。這與在任何給定時間沒有更多字節可用的情況完全不同。如果發送方對連接的剩餘時間確實沒有什麼進一步的說明,那麼關閉OutputStream作爲連接的結束。這樣做後,讀者應該檢測到流結束。你沒有提供證據表明你這樣做。

如果發送者沒有準備好關閉流,那麼您需要設計一種不同的方式讓接收者知道何時停止閱讀。這意味着在流的頂部有某種應用層協議。其中最簡單的協議之一就是發送包含固定寬度字節數的消息,然後是指定的字節數。

+0

非常感謝。那麼我將實現一個應用層協議。 –

2

我建議你直接從套接字讀取一個對象。

final ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 

public void sendMessage(Object obj) { 
    out.writeObject(obj); 
    out.reset(); 
    out.flush(); 
} 

final ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 

public Object readMessage() { 
    return in.readObject(); 
} 

總之,你需要知道什麼時候應該停止閱讀或使用一個流。

+0

感謝您的選擇。但我想知道如何用字節來完成,只是爲了更深入地瞭解緩衝區的行爲。如果你可以對字節進行一些深入的瞭解!再次感謝。 –

+0

@PabloEstrada你需要知道數據的時間。對於二進制數據,你通常會把它的長度放在它之前,這樣你就知道要讀多少。 –

+0

@PabloEstrada字節數組流在這裏完全沒有意義。它們只是浪費時間和空間。通過使用它們學習沒有什麼用處,除非不使用它們。 – EJP

相關問題