2011-02-04 50 views
1

行插座輸入流的二進制文件,所以我有一個插座InputStream在其上服務器發送包含一個數字,後跟一二進制標頭的文本行的數據流構成它正在發送的pdf文件的字節流(在標題部分中指定的長度)。我無法控制的服務器在發送數據後不會關閉數據流,因此我必須從流中讀取確切的字節數,然後從客戶端自行關閉它。我怎樣才能讀取從包括文本標題?:

所以,我的問題是,你怎麼還是有這將讓我輕鬆讀取頭(文字),然後從相同的輸入sream讀取的字節的確切數額任何事業嗎?

我已經嘗試過各種適合頭文件的Reader類,但是由於我對數據的二進制內容(Reader使用字符而不是字節)學到的不是很好。公用事業如Apache公地IOUtils因爲流保持打開/未終止,並在IOUtils.toBytes(inputStream)嘗試都會掛起不要爲我工作。

該解決方案似乎是與Stream類而不是Reader類,但它似乎如此低的水平,必須有公用事業來幫助我。使用DataInputStream讀取二進制數據似乎很容易,但我很難理解如何讀取標題。有什麼建議?

編輯:這裏是一個示例消息:

http/1.0 200 OK 
content-type: application/doc_request 
content-length: 18813 
session-id: slukdcy71292645678312 
remote-addr: slukdcy7 

<pdf binary data...> 

頭和二進制數據之間的新的線確定的標頭的端部和所述二進制數據的開始。

回答

3

可以二進制字節轉換爲文本。我建議你將所有的數據讀取爲二進制數據,並將頭文件轉換爲頭文件的二進制文本。

編輯:這裏是一個樣品溶液。它假設所有標題都是按照你的建議,並且這些文件足夠小以適應內存。你可能想要緩衝你的輸入流。

public class HttpFile { 
    public final String status; 
    public final Map<String, String> properties; 
    public final byte[] data; 

    public HttpFile(String status, Map<String, String> properties, byte[] data) { 
     this.status = status; 
     this.properties = properties; 
     this.data = data; 
    } 

    public static HttpFile readFrom(DataInputStream dis, Charset charset) throws IOException { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     int ch; 
     while((ch = dis.read()) != -1) { 
      baos.write(ch); 
      if (ch == '\n') { 
       ch = dis.read(); 
       // the second newline?? 
       if (ch == '\n') 
        break; 
       baos.write(ch); 
      } 
     } 
     String header = new String(baos.toByteArray(), charset); 
     String[] lines = header.split("\\n"); 
     String status = lines[0]; 
     Map<String, String> properties = new LinkedHashMap<String, String>(); 
     for(int i=1;i<lines.length;i++) { 
      String[] keyValue = lines[i].split(": ",2); 
      properties.put(keyValue[0], keyValue[1]); 
     } 
     byte[] data = null; 
     String content_length = properties.get("context-length"); 
     if (content_length != null) { 
      int length = Integer.parseInt(content_length); 
      dis.readFully(data = new byte[length]); 
     } 
     return new HttpFile(status, properties, data); 
    } 
} 
+0

@Peter Lawrey謝謝,但它的「讀取所有數據」位那很難,因爲我不知道有多少,除了二進制數據,我不知道,直到我讀頭。如果我在二進制數據的末尾讀取數據,它會掛起,因爲套接字是打開/未終止的。 – 2011-02-04 13:39:16