2014-03-12 34 views
0

我正在嘗試在沒有定義字節數的情況下讀取SocketChannel上的流。在TCP上通過SocketChannel讀取未定義字節數的流

我想過的另一種解決方案是將預定義大小的不同ByteBuffers存儲到一個列表中,這將允許我分配一個新的接收大小的ByteBuffer並將結果放入裏面。

的問題是,我是在阻止模式並不能找到有效的條件離開我所讀出的方法制造的循環檢查代碼:

public static final Charset charsetUTF8 = Charset.forName("UTF-8"); 
public static final int BUFFER_SIZE = 1024; 

public static String getUnbounded(String st, SocketAddress address) throws IOException { 
    SocketChannel sc = SocketChannel.open(address); 
    sc.write(charsetUTF8.encode(st)); 
    List<ByteBuffer> listBuffers = new ArrayList<>(); 
    ByteBuffer buff = ByteBuffer.allocate(BUFFER_SIZE); 
    while(sc.read(buff) > -1){ 
     if(buff.remaining() == 0){ 
      listBuffers.add(buff); 
      buff.clear(); 
     } 
    } 

    listBuffers.add(buff); 
    ByteBuffer finalBuffer = ByteBuffer.allocate(BUFFER_SIZE * listBuffers.size()); 
    for(ByteBuffer tempBuff: listBuffers){ 
    finalBuffer.put(tempBuff); 
     tempBuff.clear(); 
    } 
    finalBuffer.flip(); 

    return charsetUTF8.decode(finalBuffer).toString(); 
} 

如何解決這個任何想法?

+1

爲什麼你覺得需要使用'ByteBuffer'? – kdgregory

+0

任何命題?加上讀取方法只需要ByteBuffer – Hosni

+1

爲什麼要使用通道?您正在阻止IO,並將數據存儲到堆分配的緩衝區中。你真的認爲你通過一個簡單的'SocketInputStream'獲得*任何東西嗎? – kdgregory

回答

-1

的解決方案是讓圈外的我只好打電話:

sc.shutdownOutput(); 

其中,無需關閉讀取流關閉寫入流,並設置sc.read(BUFF)爲-1

+0

這不是您最初提出問題的解決方案。你還沒有明確說你需要在發送端調用shutdownOutput()*。* -1 – EJP

+0

我不知道我需要關閉寫入流,我只需要讓我離開的方法循環並將read()方法設置爲-1,我在問題中說出它。 – Hosni

+0

問題是,根本不應該在read()方法中:您應該知道HTTP響應中有多少個字節。 – EJP

2

你不能只是clear()字節緩衝區。你需要分配一個新的;否則重複將相同的緩衝區添加到listBuffers

ByteBuffer buff = ByteBuffer.allocate(BUFFER_SIZE); 
while(sc.read(buff) > -1){ 
    if(buff.remaining() == 0){ 
     listBuffers.add(buff); 
     buff = ByteBuffer.allocate(BUFFER_SIZE); 
    } 
} 
if (buff.position() > 0) { 
    listBuffers.add(buff); 
} 

由於最後一個緩衝區可能不會(可能不會)是滿的,你應該計算finalBuffer尺寸考慮到這一點。

+0

clear()方法在存儲之後清除ByteBuffer,然後read()方法將其新的Bytes放入 – Hosni

+1

@Hosni - 是的,但是您每次都將**相同**'ByteBuffer'對象添加到'listBuffers'。最後,當循環退出時,無論狀態爲「buff」,它都會有相同的「buff」副本。您需要爲'listBuffers'的每個元素分別創建一個對象。 –

+0

但是,因爲我已經在循環之外聲明並創建了一個ByteBuffer,所以我不能只創建另一個具有相同標識符的文件 – Hosni

0

HTTP響應流中的字節數不是'未定義的'。請參閱RFC。它是由任一定義:其中被關閉的連接的情況下

  1. EOS(HTTP 1.0或連接:關閉),
  2. 的Content-Length頭,或
  3. 解碼分塊的結果編碼格式。

重要的是要用這些方法之一來定義它,也許還有其他方法,以便HTTP持久連接可以工作,在此之後可能會有另一個響應。

我想知道你爲什麼在所有執行此,當HttpURLConnection類已經存在,與各種第三方HTTP客戶端,它已經正確地實現這一切,和許多其他的事情除了一起。

+1

http://tools.ietf.org/html/rfc2616#section-4.4 – kdgregory

+0

@kdgregory謝謝編輯在 – EJP

+0

的鏈接。因爲這是與HTTP流的例子,但我不能讓它工作與所有流 – Hosni

相關問題