簡體   English   中英

通過Java套接字接收混合媒體。 你更好嗎?

[英]Receiving mixed media over Java socket. Yours better?

我將要用Java編寫一個編程練習,我希望我的學生自己發現HTTP的內在特性,而不是讓URLConnection為他們完成所有工作。 為了估算復雜度,我想出了以下代碼段,該代碼段分析了回復(imho,這是工作中最困難的部分之一),它將返回例如“ HTTP / 1.1 200 OK” ,並推送諸如“ Server: 標頭向量中的 makato”“ content-length:1337” ,並將InputStream保留在內容的第一個字節,以便稍后可以在其上安全地構建DataInputStreamInputStreamReader

我很好奇,如果有人對Java類有更多的經驗,可以提出更優雅的替代方法。 有一件事我不是高興的是,每個人is.read()將不可避免地產生額外的系統調用(假設Socket.getInputStream()被用來飼養參數)。

public static String recvHttpHeaders(InputStream is, Vector<String> headers) 
throws Exception {
byte line[] = new byte[512];
String pending=null;
String status=null;
boolean complete=false, CR=false;
int n=0;

while (!complete) {
    int x = is.read();
    switch(x) {
    case -1: throw new Exception("something went wrong");
    case '\r': 
            if (CR) throw new Exception("encoding mismatch CRCR");
            CR=true;
            break;
    case '\n': // bare LF are accepted silently.
            String ln = new String(line,0,n,"ASCII");
            if (pending!=null) ln = pending + ln;
            if (status==null) status = ln;
            else headers.add(ln);
            complete = ln.length()==0;
            pending = null;
            n=0; CR=false;
            break;
    default:
            if (CR) throw new Exception("encoding mismatch ?CR");
            if (n>=512) {
                String part = new String(line, "ASCII");
                if (pending!=null) pending += part;
                else pending = part;
                n=0;
            }
            line[n++]=(byte)x;
            break;
    }
}
return status;
}

編輯 :誠然,有人希望在這里使用xxx.readline()以避免弄亂行的重建。 BufferedReader(或其他* Reader實際上)根據一個字符集將字節轉換為字符。 這意味着,如果我在標頭解析中使用了該功能,那么我將不再為該內容選擇該字符集。 我還沒有發現任何內置readline功能的字節級類。

性能解決方案 :感謝您指出BufferedInputStream。 我做了一些額外的測試,實際上,

   BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
   String status = recvHttpHeaders(bis, headers);
   rawCopy(bis, output);

確實減少了執行的系統調用的數量,但仍然允許我正確接收未經修改的二進制內容。

根據Sripathi Krishnan和Adam Paynter的評論,對其進行改進的方法是使用BufferedInputStream,這樣性能仍然可以接受並且不進行字符集轉換。

您應該使用BufferedReader讀取文本。 包裝您的輸入流:

BufferedReder br = new BufferedReader(new InputStreamReader(is));

然后使用readLine()逐行讀取內容:

String line = null;
while((line = br.readLine()) != null) {
    // deal with the line
}

暫無
暫無

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

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