2012-04-15 40 views
5

我的問題在於下列假設我希望是真的,因爲我相信這些,因爲我讀他們,而谷歌搜索我的問題:如何強制刷新OutputStream對象而不關閉它?

  1. 關閉套接字的OutputStream的關閉套接字太
  2. 的flush()方法的OutputStream什麼都不做

所以我基本上需要無論如何刷新我的OutputStream對象的數據爲我的應用程序工作。

如果你有興趣的細節,請參閱以下兩個鏈接:

Weird behavior : sending image from Android phone to Java server (code working)

此問題已通過關閉OutputStream解決。這樣做會將所有數據沖刷到套接字的另一端,並使我的應用程序進一步工作,但此修復很快產生了第2個問題 - 對應的套接字也被關閉:

SocketException - 'Socket is closed' even when isConnected() returns true

+2

如果你有投票權,有禮貌地解釋爲什麼 – GrowinMan 2012-04-16 01:51:07

回答

1

關閉套接字的OutputStream的關閉套接字太

真。

的OutputStream的flush()方法不執行任何操作

假。有覆蓋。請參閱Javadoc的FilterOutputStream.flush()BufferedOutputStream.flush(),ObjectOutputStream.flush(),僅舉幾例。

所以你最初的問題是不存在的,所以你不需要導致問題2的'解決方案'。

+0

但是你對於問題1的建議是什麼?最初我在OutputStream上使用flush()而不是close(),但是圖像不會被傳輸.. – GrowinMan 2012-04-16 01:49:35

+0

問題1的解決方案不是關閉流,如果對端需要流結束來知道消息何時完成,那麼您使用的應用協議只允許一條消息e,所以你需要改變它。 TCP中沒有消息,只有一個字節流。消息取決於你。 – EJP 2015-11-23 12:27:48

+0

刷新什麼都不做 - downvote看到我的回答 – ceph3us 2016-06-20 20:45:25

6

您可以調用OutputStream的flush方法而不是關閉。從OutputStream繼承的具體類將重寫flush()以執行除空之外的任何操作(將數據寫入文件或通過網絡發送)。

+0

但是,如果您看到我發佈的第一個問題,則通過套接字傳輸的圖像不會傳輸,直到OutputStream關閉。而使用flush()在這裏沒有幫助。那麼你在那裏建議什麼? – GrowinMan 2012-04-16 01:48:10

+3

在您發佈的鏈接中,服務器正在等待流中的EOF(文件結尾)。 EOF通過關閉流和TCP連接來發出信號 - 所以服務器在循環中運行,直到您關閉客戶端的輸出流。如果您不希望在傳輸圖像後關閉流,則必須在圖像傳輸完成時設計另一種信號發送方法。最簡單的方法是在發送圖像之前以整數(4字節)發送圖像大小。然後服務器可以在退出循環之前讀取該字節量。 – smichak 2012-04-16 07:30:47

2

OutputStream的flush()方法什麼也不做。

這是不正確的。

確實,由OutputStream類提供的flush()的基本實現什麼也不做。但是,您的應用將調用您正在使用的實際流類提供的該方法的版本。如果流類不具有直接寫入語義,則它將覆蓋flush()以執行所需的操作。

總之,如果需要刷新(並且它所需的一個套接字輸出流),然後調用flush()將做正確的事情。 (如果一些互聯網來源告訴你,否則它是錯誤的或者你誤解了它。)


FYI,其原因是,基OutputStream器具flush()作爲無操作是:

  • 一些輸出流類不需要衝洗時做任何事情;例如ByteArrayOutputStream
  • 對於流類,其中flush()不是無操作,所以無法在基類級別實現操作。

他們可以(理論上)設計了流API,使得OutputStream是一個抽象類(和抽象方法flush())或一個接口。然而,這個API在Java 1.0之前被有效地凍結,並且當時沒有足夠的經驗用於實際的Java編程,以實現API設計不理想。

0

你真的需要刷新嗎?我也有一個問題,在c#服務器上的監聽器無法接收從android發送的數據(我試圖同步獲取數據)。

我確定這是因爲在Android端,下面的代碼沒有刷新。

OutputStream str = btSocket.getOutputStream(); 
str.write(data_byte); 
// "This implementation does nothing" 
str.flush(); 

事實證明,如果我使用服務器上的監聽異步數據檢索 - 它得到的數據,不需要刷新()在客戶的身邊!

0

我會刺傷它。我遇到了同樣的問題。關閉輸出流是我可以「刷新」數據的唯一方法。但是因爲我仍然需要不是一個選項的輸出流。所以第一我發送字節數組的長度,out.writeInt,然後數組本身。當所有字節已被讀取,即buffer.length == in.readInt()我打破循環

ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[1024]; 
    byte[] fileBytes; 
    int n; 
    int length; 

    try 
    { 
     size = in.readInt(); 

     while((n = in.read(buffer)) != -1) 
     { 
      dataBuffer.write(buffer, 0, n); 

      if(dataBuffer.toByteArray().length == length) 
      { 
       fileBytes = dataBuffer.toByteArray(); break; 
      } 
     } 
    } 
0

我有同樣的問題。 在流尾添加「\ n」。沖洗工作,但是destinary不知道如果消息結束

0

在Android沖洗是()(基於API 23例)

public Socket() { 
    this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(); 
    this.proxy = null; 
} 

public class PlainSocketImpl extends SocketImpl { 

    @Override protected synchronized OutputStream getOutputStream() throws IOException { 
     checkNotClosed(); 
     return new PlainSocketOutputStream(this); 
    } 


} 

private static class PlainSocketOutputStream extends OutputStream { 
     // doesn't override base class flush(); 
} 

不關閉套接字,你可以關閉刷新輸出流無能爲力輸出:

protected void shutdownOutput() throws IOException 

- 這將關閉WRITE文件描述符。

代替使用輸出流可以直接寫至文件描述符或通過創建具有的OutputStream自己套接字實現其將使用在C(A Berkeley socket執行經由本地呼叫)覆蓋沖洗方法(例如。