簡體   English   中英

如何從包含文本標題的套接字輸入流中讀取二進制文件?:

[英]How can I read a binary file from a socket input stream which includes textual headers?:

好的,所以我有一個套接字InputStream服務器在其上發送一個數據流,該數據流包含多行標題文本,后面跟着一個二進制字節流,組成它發送的pdf文件(標題部分指定的長度) 。 我無法控制的服務器在發送數據后不會關閉數據流,所以我必須從流中讀取確切的字節數,然后自己從客戶端關閉它。

所以,我的問題是,你或者是否有任何實用工具可以讓我輕松讀取標題(如文本),然后從同一輸入sream中讀取確切的字節數?

我已經嘗試了各種適用於標題的Reader類,但是我已經學會了對數據的二進制內容不那么好( Reader使用字符而不是字節)。 諸如apache commons IOUtils實用程序對我來說不起作用,因為流保持打開/未IOUtils.toBytes(inputStream)並且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...>

標頭和二進制數據之間的新行確定標頭的結尾和二進制數據的開始。

您可以將二進制字節轉換為文本。 我建議您將所有數據讀取為二進制文件,並將標題轉換為二進制文件中的標題。

編輯:這是一個示例解決方案。 它假定所有標題都符合您的建議,並且文件足夠小以適應內存。 您可能希望緩沖輸入流。

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);
    }
}

暫無
暫無

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

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