从多种格式的 InputStream 中读取

Posted

技术标签:

【中文标题】从多种格式的 InputStream 中读取【英文标题】:Read from InputStream in multiple formats 【发布时间】:2011-06-27 06:57:39 【问题描述】:

我正在尝试编写一个读取 HTTP 请求和响应并解析它们的类。 由于标题是普通文本,使用 BufferedReaderreadLine 方法似乎最容易阅读它们。这显然不适用于数据体,因为它可能是二进制的,所以我想在读取标头后切换到读取原始字节。

现在,我正在做这样的事情:

InputStream input=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(input));
BufferedInputStream binstream=new BufferedInputStream(input);

问题在于 BufferedReader 正在提前读取并在我有机会使用 binstream 获取它之前从流中获取所有二进制数据。

有没有办法防止它在每次调用 readLine 时读取超出换行符的内容? 或者有没有更好的方法来读取单行 ASCII 文本和原始二进制数据?

【问题讨论】:

根据 Oracle 的文档,readLine 不应超出换行符:download.oracle.com/javase/6/docs/api/java/io/… @Argote: BufferedReader 本身只返回一行,但由于它是缓冲的,它在搜索换行符之前首先填充自己的缓冲区 - 因此,数据已经从底层流。 @Paŭlo Ebermann 啊,我明白了。 【参考方案1】:

Java 中已经有一个类用于处理 HTTP 请求和响应。您应该使用它而不是尝试自己解析响应。解析 HTTP 响应比您想象的要困难,因为您必须处理不同的编码方法。它不是响应负载中的真正原始二进制数据。 HttpURLConnection 类将为您解析标头并为您提供有效负载的 InputStream。

http://download.oracle.com/javase/1.4.2/docs/api/java/net/HttpURLConnection.html

【讨论】:

我正在编写自己的代码,因为在应用程序的一部分中,我需要忽略在另一部分中使用的 http.proxyHost 设置。 如果你找不到配置参数来做你需要的事情,我会派生一个现有的实现而不是从头开始。如另一个答案中所述,使用 Apache Commons HttpClient 执行此操作不应该有任何许可问题。 其实我只是注意到有一种方法可以强制 URLConnections 不使用代理。我想这会奏效。 这不能回答问题 - 如何Read from InputStream in multiple formats?【参考方案2】:

如果您不想像 Konstantin 建议的那样使用现成的 HTTP 客户端/服务器实现,DataInputStream 有一个readLine 方法。它已被弃用,因为它没有进行正确的转换(主要是直接字节 -> 字符转换),但我认为对于纯 ASCII 标题行你应该很好。

(您应该在 DataInputStream 下放置一个 BufferedInputStream,因为 readLine 会单独读取每个字节。)

【讨论】:

这就是我之前使用的方法,但不确定是否有更好的方法(我不确定在 Java 中使用已弃用的方法有多糟糕)。 为我工作。奇怪的是没有不被弃用的方式:(【参考方案3】:

commons-httpclient 可能会为您节省大量工作。

【讨论】:

以上是关于从多种格式的 InputStream 中读取的主要内容,如果未能解决你的问题,请参考以下文章

怎么重复使用inputStream?

从 InputStream 调整位图大小

Java如何从InputStream中读取收入大小? [复制]

java实现文件加密解密

如何克隆 InputStream 以允许从两个流(原始和克隆)中读取? [复制]

如何在 Android 上从蓝牙的 InputStream 中读取