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

目录

  • Java IO及BufferedReader.readline()的Bug
    • IO流
    • BufferedReader.readline()方法Bug
    • 源码
  • 使用BufferReader类的readLine()方法注意问题
    • 一、BufferReader类的readLine()方法
    • 二、DataInputStream类的readUTF()方法
【Java|Java IO及BufferedReader.readline()出现的Bug】
Java IO及BufferedReader.readline()的Bug
IO流
Java|Java IO及BufferedReader.readline()出现的Bug
文章图片

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

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();

原文件:
Java|Java IO及BufferedReader.readline()出现的Bug
文章图片

结果:
Java|Java IO及BufferedReader.readline()出现的Bug
文章图片

结果控制台只打印了第二行,最后还报错了空指针异常
原因:
是代码中每次调用readline()方法,就会向下读取一行所以错误代码中表示的是while 判断 的第一行不为null,打印的是第二行 ,然后写入的是第三行,在次while判断的是第四行 有内容,打印的是第五行 为null,写入的是第六行也为null,就导致了空指针异常。
修改后的代码:
String line; while ((line = bufferedReader.readLine()) != null){System.out.println(line); bufferedWriter.write(line); }

结果:
Java|Java IO及BufferedReader.readline()出现的Bug
文章图片

注意:只用readline()复制后的但是和原文件是不同,没有了换行符,如果需要可以在while循环体内加上/r/n
Java|Java IO及BufferedReader.readline()出现的Bug
文章图片


源码
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期间InstantPeriod时期LocalDateTimeSystem.out.println("复制完成:"+end+",耗时:"+ Duration.between(now,end)); }/*** 使用FileinputStream、FileOutputStream与原文件一样* 将一个文件复制一份*/public static voidcopyFile() 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)方法配套使用
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读