在多种格式中从InputStream读取数据

6
我正在尝试编写一个类,用于读取HTTP请求和响应并解析它们。由于头部是普通文本,因此最简单的方法是使用BufferedReaderreadLine方法来读取它们。但是,对于数据主体,这显然行不通,因为它可能是二进制数据,所以我想在读取完头部后切换到读取原始字节。
目前,我的做法类似于这样:
InputStream input=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(input));
BufferedInputStream binstream=new BufferedInputStream(input);

问题在于BufferedReader会预读并吞掉数据流中的所有二进制数据,导致我无法使用binstream获取它。

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


根据Oracle的文档,readLine不应该读取超出换行符:http://download.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#readLine%28%29 - Argote
3
BufferedReader本身只返回一行,但由于它是有缓冲的,它会首先填满自己的缓冲区,然后再寻找换行符 - 因此,数据已经从底层流中读取。 - Paŭlo Ebermann
@Paŭlo Ebermann 哦,我明白了,那很有道理。 - Argote
3个回答

5
如果你不想使用像Konstantin提出的现成的HTTP客户端/服务器实现,DataInputStream有一个readLine方法。由于它没有进行适当的转换(主要是直接将字节转换为字符),因此已被弃用,但我认为对于纯ASCII头行来说应该是可以的。(你应该在DataInputStream下放置一个BufferedInputStream,因为readLine会逐个字节地读取。)

那是我之前在使用的方式,但不确定是否有更好的方法(我不知道在Java中使用弃用方法有多糟糕)。 - Erin
对我有用。奇怪的是没有非弃用的方法 :( - AlikElzin-kilaka

4
Java已经有一个处理HTTP请求和响应的类了。你应该使用它来代替自己试图解析响应。解析HTTP响应比你想象的更加困难,因为你必须处理不同的编码方法。响应负载中并不是真正的原始二进制数据。HttpURLConnection类将为您解析头,并为您提供有效负载的InputStream。 http://download.oracle.com/javase/1.4.2/docs/api/java/net/HttpURLConnection.html

我正在编写自己的代码,因为在应用程序的某个部分中,我需要忽略另一部分中使用的http.proxyHost设置。 - Erin
如果找不到配置参数来实现你需要的功能,我建议你可以 fork 一个已有的实现,而不是从头开始写。使用 Apache Commons HttpClient 进行 fork 不应该会有任何许可问题,正如另一个回答中提到的那样。 - Konstantin Komissarchik
其实,我刚刚注意到有一种方法可以强制URLConnection不使用代理。我想那会起作用。 - Erin
4
这并没有回答问题 - 如何以多种格式从InputStream中读取? - AlikElzin-kilaka

2

如果涉及到HTTP请求,使用commons-httpclient可能会为您省去大量的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接