簡體   English   中英

為什么 InputStream.read() 在 inputStream 對象之前已被包裝在 BufferedReader 中時拋出“讀取超時”異常?

[英]Why does InputStream.read() throw "Read timed out" exception when the inputStream object has previously been wrapped in a BufferedReader?

我有一個來自套接字的 inputStream 對象。

這個流可以是純文本,也可以包含二進制數據。 它有一個純文本“前綴”,告訴我它具有哪種類型的數據。 我使用 BufferedReader 來讀取該前綴。 然后,如果數據類型是純文本,我繼續使用 BufferedReader 讀取其余的工作正常。

問題是當我切換回使用 InputStream 時,如果前綴表示非文本數據。 流似乎在某處丟失了,我收到了java.net.SocketTimeoutException: Read timed out相反。

代碼是這樣的:

InputStream instream = mysocket.getInputStream();
BufferedReader br = (new InputStreamReader(instream, "UTF-8")));

byte[] prefixArray = new byte[4];
br.read(prefixArray, 0, 4);
String prefix = new String(prefixArray);

if("text".equals(prefix)) {
   // continue to use br.read() here, which works fine...
}else{
   byte[] barray = new byte[arraysize]
   instream.read(barray, 0, arraysize); // THROWS "Read timed out" exception
}

這根本就不允許嗎? 一旦instream被包裝在BufferedReader ,它就不能再直接使用了嗎?

BufferedReaderReader並將數據存儲在緩沖區中以供后續讀取使用。 它一次讀取盡可能多的內容,每次清空緩沖區時,它都會向緩沖區中讀取更多內容。

您的二進制讀取超時,因為BufferedReader已經讀取了您嘗試讀取的字節。

檢測流類型只需要 4 個字節。 對這 4 個字節使用Reader是矯枉過正的。 首先直接從InputStream讀取字節,然后為text數據創建一個Reader ,例如:

InputStream instream = mysocket.getInputStream();

byte[] prefixArray = new byte[4];
int offset = 0;
int numread;
do
{
    numread = instream.read(prefixArray, offset, 4-offset);
    if (numread == -1) return;
    offset += numread;
}
while (offset < 4);
String prefix = new String(prefixArray);

if ("text".equals(prefix))
{
    BufferedReader br = new BufferedReader(new InputStreamReader(instream, "UTF-8"));
    //...
}
else
{
    byte[] barray = new byte[arraysize];
    // consider using BufferedInputStream here ...
    do
    {
        numread = instream.read(barray, 0, arraysize);
        if (numread == -1) break;
        //...
    }
    while (true);
}

或者,考慮使用BufferedInputStream進行套接字讀取,並根據需要在其上添加其他類,例如:

InputStream instream = mysocket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(instream);

byte[] prefixArray = new byte[4];
DataInputStream dis = new DataInputStream(bis);
dis.readFully(prefixArray);
String prefix = new String(prefixArray);

if ("text".equals(prefix))
{
    InputStreamReader isr = new InputStreamReader(bis, "UTF-8"));
    //...
}
else
{
    byte[] barray = new byte[arraysize];
    do
    {
        numread = bis.read(barray, 0, arraysize);
        if (numread == -1) break;
        //...
    }
    while (true);
}

暫無
暫無

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

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