FileInputStream的循环遍历判定条件为什么要用read=fileOutputStream.read()!=-1

文章探讨了在使用Java的FileInputStream类读取文件时,两次调用read()方法导致的不同结果。第一种写法由于在循环条件中和循环体内分别调用了一次read(),使得指针移动过快,可能错过文件内容。而第二种写法正确地在循环内只调用一次read(),避免了这个问题,能完整遍历文件内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天学习了FileInputStream,一开始使用的第一种写法,结果发现不正确,于是寻找原因。

准备的txt文件内容

第一种代码 

try {
            FileInputStream fileOutputStream=new FileInputStream("ruoyi-admin/src/main/java/com/ruoyi/test/io/io.txt");
            while (fileOutputStream.read()!=-1){
                System.out.println(fileOutputStream.read());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

结果

 

第二种代码

 try {
            FileInputStream fileOutputStream=new FileInputStream("ruoyi-admin/src/main/java/com/ruoyi/test/io/io.txt");
            int read;
            while ((read=fileOutputStream.read())!=-1){
                System.out.println(read);
            }
            System.out.println(fileOutputStream.read());

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

结果

 两种写法的结果不一样,但是明显的是第二种遍历的结果才是正确的,

原因是FileInputStream 中的read()方法只要调用一次指针的位置就会往后挪一位。第一种方法,遍历一次就执行了两次read()方法,进入第一次到循环体时就执行第二次read()方法,所以输出98,第二次进入循环体就执行第四次read()方法,此时txt中的内容已在第二次判断时read完毕,指针后无字节,自动返回-1。

import java.io.IOException; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; public class fileDemo { public static void main(String[] args) throws IOException { method1(); method2(); method3(); method4(); } // 一次读取一个字节 public static void method1() throws IOException { FileInputStream fis=new FileInputStream("D:\\bbb.mp4"); FileOutputStream fos = new FileOutputStream("copy.mp4"); long start1 = System.currentTimeMillis(); int b=0; while((b=fis.read())!=-1) { //System.out.println((char)b); fos.write((char)b); } long end1 = System.currentTimeMillis(); System.out.println("使用FileInputStreamread()方法复制时间:" + (end1 - start1) + "ms"); fis.close(); fos.close(); } // 一次读取一个字节数组 public static void method2() throws IOException { FileInputStream fis=new FileInputStream("D:\\bbb.mp4"); FileOutputStream fos = new FileOutputStream("copy.mp4"); long start1 = System.currentTimeMillis(); int b=0; byte[] bs=new byte[1024]; while((b=fis.read(bs))!=-1) { //System.out.println(new String(bs)); fos.write(bs,0,b); } long end1 = System.currentTimeMillis(); System.out.println("使用FileInputStreamreadread(byte[] b)方法复制时间:" + (end1 - start1) + "ms"); fis.close(); fos.close(); } // 缓冲流+一次读一个字节 public static void method3() throws IOException { BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\bbb.mp4")); FileOutputStream fos = new FileOutputStream("copy.mp4"); long start1 = System.currentTimeMillis(); int b=0; while((b=bis.read())!=-1) { //System.out.println((char)(b)); fos.write((char)b); } long end1 = System.currentTimeMillis(); System.out.println("使用BufferedInputStream的read()方法复制时间:" + (end1 - start1) + "ms"); bis.close(); fos.close(); } //缓冲流+一次读一个字节数组 public static void method4() throws IOException { BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\bbb.mp4")); FileOutputStream fos = new FileOutputStream("copy.mp4"); long start1 = System.currentTimeMillis(); int len=0; byte[] bs=new byte[1024]; while((len=bis.read(bs))!=-1) { //System.out.println(new String(bs,0,len)); fos.write(bs,0,len); } long end1 = System.currentTimeMillis(); System.out.println("使用BufferedInputStream的read(byet[] b)方法复制时间:" + (end1 - start1) + "ms"); bis.close(); fos.close(); } } 给出每一行代码的注释
05-24
``` import java.io.IOException; // 导入IOException类 import java.io.FileOutputStream; // 导入FileOutputStream类 import java.io.FileInputStream; // 导入FileInputStream类 import java.io.BufferedInputStream; // 导入BufferedInputStream类 public class fileDemo { // 定义fileDemo类 public static void main(String[] args) throws IOException { // 主函数,抛出IOException异常 method1(); // 调用method1函数 method2(); // 调用method2函数 method3(); // 调用method3函数 method4(); // 调用method4函数 } // 一次读取一个字节 public static void method1() throws IOException { // 定义method1函数,抛出IOException异常 FileInputStream fis=new FileInputStream("D:\\bbb.mp4"); // 创建FileInputStream对象fis,打开文件D:\bbb.mp4 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 创建FileOutputStream对象fos,打开文件copy.mp4 long start1 = System.currentTimeMillis(); // 获取当前时间 int b=0; // 定义整型变量b并初始化为0 while((b=fis.read())!=-1) { // 当读取到的字节不等于-1时,执行循环 //System.out.println((char)b); // 输出读取到的字节 fos.write((char)b); // 将读取到的字节写入文件 } long end1 = System.currentTimeMillis(); // 获取当前时间 System.out.println("使用FileInputStreamread()方法复制时间:" + (end1 - start1) + "ms"); // 输出复制所用时间 fis.close(); // 关闭文件输入流 fos.close(); // 关闭文件输出流 } // 一次读取一个字节数组 public static void method2() throws IOException { // 定义method2函数,抛出IOException异常 FileInputStream fis=new FileInputStream("D:\\bbb.mp4"); // 创建FileInputStream对象fis,打开文件D:\bbb.mp4 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 创建FileOutputStream对象fos,打开文件copy.mp4 long start1 = System.currentTimeMillis(); // 获取当前时间 int b=0; // 定义整型变量b并初始化为0 byte[] bs=new byte[1024]; // 创建1024字节的字节数组bs while((b=fis.read(bs))!=-1) { // 当读取到的字节不等于-1时,执行循环 //System.out.println(new String(bs)); // 输出读取到的字节 fos.write(bs,0,b); // 将读取到的字节写入文件 } long end1 = System.currentTimeMillis(); // 获取当前时间 System.out.println("使用FileInputStreamreadread(byte[] b)方法复制时间:" + (end1 - start1) + "ms"); // 输出复制所用时间 fis.close(); // 关闭文件输入流 fos.close(); // 关闭文件输出流 } // 缓冲流+一次读一个字节 public static void method3() throws IOException { // 定义method3函数,抛出IOException异常 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\bbb.mp4")); // 创建BufferedInputStream对象bis,打开文件D:\bbb.mp4 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 创建FileOutputStream对象fos,打开文件copy.mp4 long start1 = System.currentTimeMillis(); // 获取当前时间 int b=0; // 定义整型变量b并初始化为0 while((b=bis.read())!=-1) { // 当读取到的字节不等于-1时,执行循环 //System.out.println((char)(b)); // 输出读取到的字节 fos.write((char)b); // 将读取到的字节写入文件 } long end1 = System.currentTimeMillis(); // 获取当前时间 System.out.println("使用BufferedInputStream的read()方法复制时间:" + (end1 - start1) + "ms"); // 输出复制所用时间 bis.close(); // 关闭缓冲输入流 fos.close(); // 关闭文件输出流 } // 缓冲流+一次读一个字节数组 public static void method4() throws IOException { // 定义method4函数,抛出IOException异常 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\bbb.mp4")); // 创建BufferedInputStream对象bis,打开文件D:\bbb.mp4 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 创建FileOutputStream对象fos,打开文件copy.mp4 long start1 = System.currentTimeMillis(); // 获取当前时间 int len=0; // 定义整型变量len并初始化为0 byte[] bs=new byte[1024]; // 创建1024字节的字节数组bs while((len=bis.read(bs))!=-1) { // 当读取到的字节数不等于-1时,执行循环 //System.out.println(new String(bs,0,len)); // 输出读取到的字节 fos.write(bs,0,len); // 将读取到的字节数组写入文件 } long end1 = System.currentTimeMillis(); // 获取当前时间 System.out.println("使用BufferedInputStream的read(byet[] b)方法复制时间:" + (end1 - start1) + "ms"); // 输出复制所用时间 bis.close(); // 关闭缓冲输入流 fos.close(); // 关闭文件输出流 } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值