【问题标题】:BufferedReader and Sockets in javajava中的BufferedReader和Sockets
【发布时间】:2015-05-10 19:51:54
【问题描述】:

假设我正在使用这样的 Socket InputStream,以便读取以下数据:
(第一部分用 ASCII 编码)

    the rest of this message is binaryCRLF  
    01100110010...

代码:

InputStreamReader isr = new InputStreamReader(socket.getInputStream()); 
BufferedReader in = new BufferedReader(isr);
String line = in.readLine();

我现在期望的是line 包含文本:

这条消息的其余部分是二进制的

那我想用原来的socket InputStream:

 InputStream is = socket.getInputStream();  
    ...

读取消息的二进制部分。

现在,如果 BufferedReader 缓冲了一些二进制数据怎么办,
这将是一个问题,因为我会错过部分数据。
我错过了什么吗?

【问题讨论】:

  • 你的方法有效吗?
  • 这更多的是对缓冲输入流的工作原理缺乏了解,而不是实际问题。

标签: java sockets http web stream


【解决方案1】:

the source of BufferedReader 中,您将看到默认缓冲区大小为 8192。因此,readLine() 的调用将读取比第一行更多的字节到缓冲区中。

使用不同的方法。缓冲输入并读取两次。

【讨论】:

  • 我的示例类似于浏览器为了向用户显示网页内容而必须执行的操作。他们如何处理此问题?
  • 它们不混合字符和字节。 HTTP 是一个带有 Content-Type 和 Content-Length 等标头的协议。看一下 HTTP 解析器的源代码。
  • 作为同一问题的一部分,InputStreamReader 的 API 报告说它可以缓冲字节,尽管它不是缓冲流。这是什么意思?
【解决方案2】:

试试


InputStreamReader isr = new InputStreamReader(socket.getInputStream()); 
BufferedReader in = new BufferedReader(isr);
String line ="";
String buffer="";
while((buffer= in.readLine()) != null){ 
  line.concat(buffer); 
}

这样,在 BufferedReader 中有数据之前,您可以将其读入一行,并且不会丢失任何缓冲数据。干杯.. :)


同样为了更快的 IO,使用 nio(New Input Output) 库,尤其是 ByteBuffer 对象,您还可以使用 flush() 从流中刷新数据。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 2015-09-27
  • 2015-05-10
  • 2015-11-12
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
相关资源
最近更新 更多