JAVA语言用buffer读取流数据不对的问题分析
小标 2018-11-05 来源 : 阅读 1180 评论 0

摘要:本文主要向大家介绍了JAVA语言用buffer读取流数据不对的问题分析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言用buffer读取流数据不对的问题分析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。


背景: 项目中采用了BufferedReader, 调用readline()方法读取流中的一行,导致代码在编译时对readline() 方法报了CodeDex, 为了清理CodeDex,坑就挖出来了。


1. 挖坑


代码原来大概是这样的:


public class MyTest1 {

 

 public static void main(String[] args) throws IOException {

 

  File file = new File("C:\\Users\\Administrator\\Desktop\\myTest1.txt");

 

  InputStream is = new FileInputStream(file);

  InputStreamReader isr = new InputStreamReader(is);

  BufferedReader bf = new BufferedReader(isr);

 

  String line;

  StringBuilder sb = new StringBuilder();

 

  while(null != (line = bf.readLine())) {

sb.append(line).append("\n"); //注意readline时会把换行符弄没了

  }

  System.out.println(sb.toString());

 

 }

}

   



整改后的代码大概是这样子的:


public class MyTest {

 

 public static void main(String[] args) throws IOException {

 

  File file = new File("C:\\Users\\Administrator\\Desktop\\myTest1.txt");

 

  InputStream is = new FileInputStream(file);

  InputStreamReader isr = new InputStreamReader(is);

 

 

  StringBuilder sb = new StringBuilder();

 

  char[] buffer = new char[200];

 

  while (-1 != isr.read(buffer)) {

//这样代码是有问题的.......

sb.append(buffer);

  }

 

  String result = sb.toString();

 

  System.out.println(result);

 

  isr.close();

  is.close();

 

 }

}

   



2. 分析


最后的结果总是不对,大概扫了结果发现最后的内容不是真正末尾的内容,以为是读少了,各种折腾。。最后沉下心来,才发现是读多了。为什么呢?


InputStreamReader.read(char[] buffer)方法,其实是将每次从流中读到的内容按照顺序依次赋值给buffer[0], buffer[1],buffer[2]…, 前几次由于内容多,buffer小,每次循环读取都把 buffer[0] 到 buffer[buffer.length-1] 全部赋值了,没问题。。


等到最后一次读的时候, 流的内容就没有整个buffer可以容纳的多了, 可能读取的时候把 buffer[0] 到 buffer[n] 位置重新赋值, 这个时候, buffer[n+1] 到 buffer[buffer.length-1] 还是上次的旧值。。 (0 < n < = buffer.length-1)


再看:


我们每次是StringBuilder.append(char[] bufffer) 方法,把整个buffer append进去的,最后一次也不例外。。, 这就导致了最终得到的字符串 读多了。。。。


3. 解决办法


解决办法如下:


public class MyTest {

 

 public static void main(String[] args) throws IOException {

 

  File file = new File("C:\\Users\\Administrator\\Desktop\\myTest1.txt");

 

  InputStream is = new FileInputStream(file);

  InputStreamReader isr = new InputStreamReader(is);

 

  StringBuilder sb = new StringBuilder();

  char[] buffer = new char[200];

 

  int len;

  while (-1 != (len = isr.read(buffer))) {

//调用append(char[] str, int offset, int len) 方法,注意第三个参数len是流真正读取的长度

//另外注意该方法与append(char[] str)方法的区别

sb.append(buffer, 0, len);

  }

 

  String result = sb.toString();

  System.out.println(result);

 

  isr.close();

  is.close();

 

 }

}

   



注意的地方在代码里已经标注了。


这次填坑花了不少时间,特此记录一下。


睡觉了。。


          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved