[英]Receiving mixed media over Java socket. Yours better?
我將要用Java編寫一個編程練習,我希望我的學生自己發現HTTP的內在特性,而不是讓URLConnection為他們完成所有工作。 為了估算復雜度,我想出了以下代碼段,該代碼段分析了回復(imho,這是工作中最困難的部分之一),它將返回例如“ HTTP / 1.1 200 OK” ,並推送諸如“ Server: 標頭向量中的“ makato”和“ content-length:1337” ,並將InputStream保留在內容的第一個字節,以便稍后可以在其上安全地構建DataInputStream或InputStreamReader 。
我很好奇,如果有人對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.