Java IO及BufferedReader.readline()出现的Bug

目录
  • Java IO及BufferedReader.readline()的Bug
    • IO流
    • BufferedReader.readline()方法Bug
    • 源码
  • 使用BufferReader类的readLine()方法注意问题
    • 一、BufferReader类的readLine()方法
    • 二、DataInputStream类的readUTF()方法

Java IO及BufferedReader.readline()的Bug

IO流

:流是一组有序的,有起点和终点的字节集合,是对计算机中数据传输的总称。即数据在两个设备间的传输称为流,流的本质是数据传输

BufferedReader.readline()方法Bug

错误代码:

		File testTxt = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test.txt");
		File file_copy3 = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test_copy3.txt");
        BufferedReader bufferedReader = new BufferedReader(new FileReader(testTxt));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file_copy3));
        //readLine() 每次读取一行
        while (bufferedReader.readLine() != null){
            System.out.println(bufferedReader.readLine());
            bufferedWriter.write(bufferedReader.readLine());
        }
        bufferedWriter.close();
        bufferedReader.close();

原文件:

结果:

结果控制台只打印了第二行,最后还报错了空指针异常

原因:

是代码中每次调用readline()方法,就会向下读取一行所以错误代码中表示的是while 判断 的第一行不为null,打印的是第二行 ,然后写入的是第三行,在次while判断的是第四行 有内容,打印的是第五行 为null,写入的是第六行也为null,就导致了空指针异常。

修改后的代码:

	 	String line;
        while ((line = bufferedReader.readLine()) != null){
            System.out.println(line);
            bufferedWriter.write(line);
        }

结果:

注意:只用readline()复制后的但是和原文件是不同,没有了换行符,如果需要可以在while循环体内加上/r/n

源码

package com.lsh.io;
import java.io.*;
import java.time.Duration;
import java.time.Instant;
/**
 * @author :LiuShihao
 * @date :Created in 2021/3/3 11:09 上午
 * @desc :  只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
 *
 */
public class FileIO {
    public static File testTxt = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test.txt");
    public static File catImg = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/cat.jpg");
    public static void main(String[] args) throws Exception {
        Instant now = Instant.now();
        System.out.println("开始复制:"+now);
//        copyFile();
//        copyByReaderAndWriter1();
        copyByReaderAndWriter2();
        Instant end = Instant.now();
        // Duration  期间Instant          Period  时期  LocalDateTime
        System.out.println("复制完成:"+end+",耗时:"+ Duration.between(now,end));
    }
    /**
     * 使用FileinputStream、FileOutputStream   与原文件一样
     * 将一个文件复制一份
     */
    public static void  copyFile() throws Exception {
//        File file = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test.txt");
        File file_copy1 = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test_copy.txt");
//        File file_copy1 = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/cat_copy.jpg");
        FileInputStream fis = new FileInputStream(testTxt);
        FileOutputStream fos = new FileOutputStream(file_copy1);
        //byte[] bytes = new byte[1024];
        byte[] bytes = new byte[fis.available()];
        int read = fis.read(bytes);
        if (read != -1){
            fos.write(bytes);
        }
        fis.close();
        fos.close();
    }
    /**
     * 字符流
     * 使用FileInputStream、FileOutputStream、InputStreamReader、OutputStreamWriter、BufferedReader、BufferedWriter 复制文件
     *
     * readLine() 不用while的判断只会输出一行。
     */
    public static void copyByReaderAndWriter1() throws Exception {
//        File testTxt = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test.txt");
        File file_copy2 = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test_copy2.txt");
        FileInputStream fis = new FileInputStream(testTxt);
        FileOutputStream fos = new FileOutputStream(file_copy2);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fos));
        String line;
        while ((line = bufferedReader.readLine()) != null){
            System.out.println(line);
            bufferedWriter.write(line);
        }
        // 注意: fis、fos要在bufferedWriter、bufferedReader关闭之后,否则会报错!
        bufferedWriter.close();
        bufferedReader.close();
        fis.close();
        fos.close();
    }
    /**
     * 字符流
     * 使用BufferedReader、BufferedWriter、FileReader、FileWriter复制文件
     * @throws Exception
     */
    public static void copyByReaderAndWriter2() throws Exception{
        File file_copy3 = new File("/Users/LiuShihao/IdeaProjects/netty_demo/src/main/resources/test_copy3.txt");
        BufferedReader bufferedReader = new BufferedReader(new FileReader(testTxt));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file_copy3));
        //readLine() 每次读取一行
        String line;
        while ((line = bufferedReader.readLine()) != null){
            System.out.println(line);
            bufferedWriter.write(line);
        }
        bufferedWriter.close();
        bufferedReader.close();
    }
}

使用BufferReader类的readLine()方法注意问题

一、BufferReader类的readLine()方法

public String readLine():直到程序遇到了换行符或者是对应流的结束符,该方法才会认为读到了一行,才会结束其阻塞,让程序继续往下执行。

注意:读取到没有数据时就返回null(因为其它read()方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null。

读取一个文本行,通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。

返回:到达流末尾,就返回null。

注意:当循环读取文件内容时,循环条件的结束要注意使用正确。

错误的使用方式:

String valueString = null;
   while (bf.readLine()!=null){        //这样会造成数据丢失,因为在这里已经调用了readLine()方法,已经读取了一行,下次调用时,就会丢失一行。
        System.out.println(valueString);
}

正确的解决方法:用一个变量来接收方法的返回值

String valueString = null;
   while ((valueString=bf.readLine())!=null){     //通过变量来接收数据,避免数据丢失
        System.out.println(valueString);
}

二、DataInputStream类的readUTF()方法

readUTF读取的必须是writeUTF()写下的字符串。即DataOutputStream的 writeUTF(String str)方法配套使用

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 基于自定义BufferedReader中的read和readLine方法

    实例如下所示: package day0208; import java.io.FileReader; import java.io.IOException; /* * 自定义读取缓冲区,实现BufferedReader功能 * 分析: * 缓冲区就是封装了一个数组,并对外提供了更多的方法对数组进行访问 * 其实这些方法最终操作的都是数组的角标 * 缓冲的原理: * 其实就是从源中获取一批数据装进缓冲区,再从缓冲区取出数据 * 当此次取完后,继续从源中取出一批数据到缓冲区 * 当源中的数据取光时

  • InputStreamReader和BufferedReader用法及实例讲解

    一.BufferedReader类 . 所属类库: java.lang.Object java.io.Reader java.io.BufferedReader . 基本概念 : public class BufferedReader    extends Reader 从字符输入流中读取文本,缓冲各个字符,从而实现字符.数组和行的高效读取. 可以指定缓冲区的大小,或者可使用默认的大小.大多数情况下,默认值足够大. 通常, Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取

  • 解决bufferedReader.readLine()读到最后发生阻塞的问题

    bufferedReader.readLine()读到最后发生阻塞 最近在做一个imageserver,需求简化后就是使用socket响应HTTP请求从而截取所需要的数据流,写入到服务器端的文件中,从而完成客户端将图片上传到服务器. 因为从客户端得到的数据流中,我们只希望截取其中的一部分.这样就使我们无法像经常那样边读边向文件中写入,而且在流已经读到末尾时,使用bufferedInputStream.read()>0或inputStream.read()>0作为while语句结束的判断条件在使

  • Java IO及BufferedReader.readline()出现的Bug

    目录 Java IO及BufferedReader.readline()的Bug IO流 BufferedReader.readline()方法Bug 源码 使用BufferReader类的readLine()方法注意问题 一.BufferReader类的readLine()方法 二.DataInputStream类的readUTF()方法 Java IO及BufferedReader.readline()的Bug IO流 流:流是一组有序的,有起点和终点的字节集合,是对计算机中数据传输的总称.

  • Java输入流Scanner/BufferedReader使用方法示例

    1.使用Scanner 使用时需要引入包import java.util.Scanner;首先定义Scanner对象 Scanner sc = new Scanner(System.in);如果要输入整数,则 int n = sc.nextInt();String类型的,则String temp = sc.next(); 比如: 复制代码 代码如下: import java.util.Scanner; public class Test {    @SuppressWarnings("resou

  • java IO流文件的读写具体实例

    引言: 关于java IO流的操作是非常常见的,基本上每个项目都会用到,每次遇到都是去网上找一找就行了,屡试不爽.上次突然一个同事问了我java文件的读取,我一下子就懵了第一反应就是去网上找,虽然也能找到,但自己总感觉不是很踏实,所以今天就抽空看了看java IO流的一些操作,感觉还是很有收获的,顺便总结些资料,方便以后进一步的学习... IO流的分类:1.根据流的数据对象来分:高端流:所有的内存中的流都是高端流,比如:InputStreamReader  低端流:所有的外界设备中的流都是低端流

  • Java IO 之文件读写简单实例

    Java IO 之文件读写简单实例 1.文件读 public class ReadFromFile { /** * 以字节为单位读取文件,常用于读二进制文件,如图片.声音.影像等文件. */ public static void readFileByBytes(String fileName) { File file = new File(fileName); InputStream in = null; try { System.out.println("以字节为单位读取文件内容,一次读一个字

  • 【Java IO流】字节流和字符流的实例讲解

    字节流和字符流 对于文件必然有读和写的操作,读和写就对应了输入和输出流,流又分成字节和字符流. 1.从对文件的操作来讲,有读和写的操作--也就是输入和输出. 2.从流的流向来讲,有输入和输出之分. 3.从流的内容来讲,有字节和字符之分. 这篇文章先后讲解IO流中的字节流和字符流的输入和输出操作. 一.字节流 1)输入和输出流 首先,字节流要进行读和写,也就是输入和输出,所以它有两个抽象的父类InputStream.OutputStream. InputStream抽象了应用程序读取数据的方式,即

  • Java IO文件编码转换实现代码

    对IO操作真心不是很懂...对编码.乱码也是一知半解...今天遇到了一个需求,要求将一个文件进行编码转换,并且返回编码后的字符串,如原本的GBK编码,转换为UTF-8 其中这个BytesEncodingDetect 类就不贴了.主要用了里面的获取文件编码格式. 刚开始试了直接在源文件修改编码方式,采用URLEncoder和URLDecoder进行转换,却迟迟不行.出现了中文奇数最后一个字乱码 百度找了解决方法,都未果,只好采用我的思路是:先读取源文件的内容,存放到StringBuffer里面,然

  • 简单总结Java IO中stream流的使用方法

    Java语言的输入输出功能是十分强大而灵活的,对于数据的输入和输出操作以"流"(stream)的方式进行.J2SDK提供了各种各样的"流"类,用以获取不同种类的数据,定义在包java.io中.程序中通过标准的方法输入或输出数据. Java中的流可以从不同的角度进行分类: 按照流的方向不同:分为输入流和输出流. 按照处理数据单位的不同:分为字节流(8位)和字符流(16位). 按照功能不同:分为节点流和处理流. 节点流:是可以从一个特定的数据源(节点)读写数据的流(例如

  • JAVA IO API使用详解

    一.理论准备流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以"流"的方式进行,设备可以是文件.网络.内存等.流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序(小马哥说的是机器)为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流,可以将流想象成一个"水流管道"(很多资料都这么讲的),自然就出现了方向的概念.流把I/O设备内部的具体操作给隐藏起来了.所有InputStream和Reader的派

  • Java IO读取文件的实例详解

    Java中文件流的两个主要方式就是字符流和字节流,如下图: 具体的使用方法可以参考官方文档,这里主要介绍四种常见的文件读取方式 1.通过字节来读取文件(常用于二进制文件:图片.声音.视频等) 2.通过字符来读取文件(常用于文本的读取) 3.通过行来读取文件(常用于面向行的格式化文本读取) 4.随机读取文件(基于字节来读取) 下面是对于这四种读取方式的代码,如下: package com.ds.io; //1.按字节读取文件内容 //2.按字符读取文件内容 //3.按行读取文件内容 //4.随机读

  • Java 中的 BufferedReader 介绍_动力节点Java学院整理

    BufferedReader 介绍 BufferedReader 是缓冲字符输入流.它继承于Reader. BufferedReader 的作用是为其他字符输入流添加一些缓冲功能. BufferedReader 函数列表 BufferedReader(Reader in) BufferedReader(Reader in, int size) void close() void mark(int markLimit) boolean markSupported() int read() int

随机推荐