采坑_java用buffer读取流数据不对

背景: 项目中采用了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();

    }
}

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

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

睡觉了。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值