【问题标题】:Is it possible to peek HttpClient's org.apache.http.conn.EofSensorInputStream?是否可以窥视 HttpClient 的 org.apache.http.conn.EofSensorInputStream?
【发布时间】:2017-11-12 10:33:02
【问题描述】:

我正在尝试查看来自 HttpClient 的输入流内容,最多 64k 字节。

流来自一个 HttpGet,没什么特别的:

HttpGet requestGet = new HttpGet(encodedUrl); HttpResponse httpResponse = httpClient.execute(requestGet); int status = httpResponse.getStatusLine().getStatusCode(); if (status == HttpStatus.SC_OK) { return httpResponse.getEntity().getContent(); }

它返回的输入流的类型是org.apache.http.conn.EofSensorInputStream

我们的用例是这样的,我们需要“窥视”输入流的第一个(最多 64k)字节。我使用这里描述的算法How do I peek at the first two bytes in an InputStream?

PushbackInputStream pis = new PushbackInputStream(inputStream, DEFAULT_PEEK_BUFFER_SIZE); byte [] peekBytes = new byte[DEFAULT_PEEK_BUFFER_SIZE]; int read = pis.read(peekBytes); if (read < DEFAULT_PEEK_BUFFER_SIZE) { byte[] trimmed = new byte[read]; System.arraycopy(peekBytes, 0, trimmed, 0, read); peekBytes = trimmed; } pis.unread(peekBytes);

当我使用 ByteArrayInputStream 时,这没有问题。

问题:使用org.apache.http.conn.EofSensorInputStream 时,我只在流的开头得到少量字节。通常大约 400 字节。当我预计最多 64k 字节时。

我还尝试使用BufferedInputStream 读取前64k 字节,然后调用.reset(),但这也不起作用。同样的问题。

为什么会这样?我不认为有任何东西会关闭流,因为如果你打电话给IOUtils.toString(inputStream),我会得到所有的内容。

【问题讨论】:

    标签: java httpclient inputstream


    【解决方案1】:

    InputStream#read(byte[] b,int off,int len)合约:

    从输入流中读取最多 len 个字节的数据到一个数组中 字节。尝试读取多达 len 个字节,但是一个 可以读取较小的数字。实际读取的字节数为 以整数形式返回

    不要使用这种方法,而是使用IOUtils.read,它会一直读取直到您在循环中获得您请求的字节数。

    【讨论】:

    • 该死!知道如何让它返回更多吗?我只是使用偏移量并提出另一个请求吗?你确定这不仅仅是说如果它没有更多的剩余它将返回更少的字节吗?
    • 是的,我很确定。您只需要继续循环读取,直到接收到所需的数据量或达到流结束。
    • 这不起作用。 available() 返回 0。它认为流是空的,所以添加你建议的循环什么也没做。
    • 而不是使用来自 InputStream 的read,而是使用IOUtils.read()(我们正在讨论的循环)有效!。所以无视我之前的评论。
    猜你喜欢
    • 2014-01-18
    • 2011-09-07
    • 2013-02-25
    • 2022-11-15
    • 2012-08-31
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多