2011-02-04 13 views
1

これで、サーバがヘッダのテキスト行数を含むデータストリームを送信しているソケットInputStreamをバイナリで送信しています送信しているpdfファイルを構成するバイトのストリーム(ヘッダセクションで指定された長さの)私は制御できないサーバーはデータを送信した後でデータストリームを閉じないので、ストリームから正確なバイト量を読み込み、クライアント側からそれを閉じる必要があります。テキストヘッダを含むソケット入力ストリームからバイナリファイルを読み取るにはどうすればいいですか?

私の質問は、ヘッダー(テキスト)を読みやすくして、同じ入力ストリームから正確な量のバイトを読み込むためのユーティリティはどうやっていますか?

私はさまざまなヘッダーに適したクラスを試しましたが、データのバイナリコンテンツ(バイトではない文字でのReaderの作業)にはそれほど大きくはなかったことが分かっています。ストリームはオープン/非終了のままで、IOUtils.toBytes(inputStream)での試行は無期限にハングアップするため、ApacheのコモンIOUtilsなどのユーティリティは動作しません。

解決策は、Readerクラスではなく、Streamクラスで動作するように思われますが、これは私にこれを手助けするユーティリティがなければならないほど低レベルのようです。 DataInputStreamを使ってバイナリデータを読むのは簡単だと思われますが、ヘッダーの読み方は分かりません。何かアドバイス?

EDIT:

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

<pdf binary data...> 

ヘッダとバイナリデータとの間の新しいラインは、ヘッダの終わりとバイナリデータの開始を決定する:ここでサンプルメッセージです。

答えて

3

バイナリバイトをテキストに変換できます。私は、バイナリとしてすべてのデータを読んで、ヘッダーのバイナリからテキストにヘッダーを変換することをお勧めします。

EDIT:ここではサンプルソリューションです。これは、すべてのヘッダーがあなたが示唆したとおりであり、ファイルがメモリに収まるのに十分小さいと想定しています。入力ストリームをバッファリングすることができます。

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のおかげで、私は、私は、ヘッダーを読むまで、私は知らないバイナリデータを除いて、そこにあるどのくらいかわからないので、そのハードのthatsビット「すべてのデータの読み取り」を。バイナリデータの最後を読み取ると、ソケットがオープン/ターミネータされていないため、ハングします。 –

+0

コンテンツがどこにあるのかを判断できる必要があります。例えばhttpヘッダーの末尾に空白行があるのか​​、ヘッダーにデータの長さが含まれていますか?サンプルヘッダーの外観を投稿できますか? –

+0

あなたはサーバーを制御できないかもしれませんが、送信したメッセージのデコード方法を尋ねることはできますか?つまり、ヘッダーとファイルの末尾がどこにあるかをどのように知っていると思いますか?あなたが推測していることを知らずに、データのフォーマットに依存します。 –

関連する問題