分享下我的IO流学习笔记,很详细的

IO流是java语言中非常重要的知识点以后会经常用到,所以要熟练掌握,分享下我的笔记,复习的时候看看很方便

一.IO流

  • 1.概念
    • IO流用来处理设备之间的数据传输
    • Java对数据的操作是通过流的方式
    • Java用于操作流的类都在IO包中
    • 流按流向分为两种:输入流,输出流。
    • 流按操作类型分为两种:
      • 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
      • 字符流 : 字符流只能操作纯字符数据,比较方便。
  • 2.IO流常用父类
    • 字节流的抽象父类:
      • InputStream
      • OutputStream
    • 字符流的抽象父类:
      • Reader
      • Writer
  • 3.IO程序书写
    • 使用前,导入IO包中的类
    • 使用时,进行IO异常处理
    • 使用后,释放资源

二.字节流

  • 1.常用方法
    • InputStream:
      • read() 读取一个字节
      • read(byte[]) 读取若干(数组长度)字节
      • available() 获取可读的字节数
      • close() 关闭流, 释放资源
    • OutputStream:
      • write(int) 写出一个字节
      • write(byte[]) 写出数组中的所有字节
      • write(byte[],start,len);
      • close() 关闭流, 释放资源
  • 2.读取文件
    • 创建FileInputStream对象, 指定一个文件. 文件必须存在, 不存在则会抛出FileNotFoundException
    • 使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1
    • 读取结束后需要释放资源, 调用close()方法关闭输入流
  • 输入流代码
    FileInputStream fis = new FileInputStream("xxx.txt");       //创建流对象,关联xxx.txt文件
    int b;
    while((b = fis.read()) != -1) {                             //将每次读到的结果赋值给b
        System.out.println(b);
    }
    
    fis.close();
    
    • 为什么read方法返回是int而不是byte类型呢?
      • 因为如果读取的是视频文件或音频文件或图片文件等,在读取过程中很有可能会遇到11111111,也就是byte类型的-1,那么遇到-1程序就会停止读取,
        会漏掉文件,为了防止这种情况出现,把byte类型提升为int类型,在这个字节前补上24个0,把遇到的-1变成255,这样可以保证将整个文件读完
  • 3.写出文件
    • 创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.
    • 使用write()方法可以向文件写出一个字节.
    • 写出结束后同样需要调用close()
  • 输出流代码
    FileOutputStream fos = new FileOutputStream("aaa.txt"); //创建流对象,关联aaa.txt
    fos.write(100);                                         //写出数据的时候会将前面24个0去掉,写出的是一个字节
    fos.write(98);
    fos.write(99);
    fos.close();                                            //关闭流,释放资源
    
  • 4.拷贝文件

    • 可以从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低
    • 我们可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出1byte = 8bit
    • 1,逐个字节拷贝

      FileInputStream fis = new FileInputStream("致青春.mp3");       //创建输入流对象,关联致青春.mp3
      FileOutputStream fos = new FileOutputStream("copy.mp3");    //创建输出流对象,关联copy.mp3
      
      int b;
      while((b = fis.read()) != -1) {                             //将每次读到的赋值给b
          fos.write(b);                                           //将b中的字节写出去
      }
      
      fis.close();                                                //关流,释放资源
      fos.close();  
      
    • 2,自定义数组拷贝

      FileInputStream fis = new FileInputStream("致青春.mp3");       //创建输入流对象,关联致青春.mp3
      FileOutputStream fos = new FileOutputStream("copy.mp3");    //创建输出流对象,关联copy.mp3
      byte[] arr = new byte[1024 * 8];                            //自定义数组
      int len;
      while((len = fis.read(arr)) != -1) {                            //将数据读到字节数组中
          fos.write(arr, 0, len);                                 //从字节数组中将数据写到文件上
          //fos.write(arr);
      }
      
      fis.close();                                                //关流,释放资源
      fos.close();
      
      int len = read(arr);如果文件上有数据返回的就是读到有效的字节个数,如果文件上没有数据返回的就是-1
      
    • 3,定义一个大数组拷贝,数组和文件的字节个数一样大

      //fis.available();一次获取读的文件的大小
      FileInputStream fis = new FileInputStream("致青春.mp3");
      FileOutputStream fos = new FileOutputStream("copy.mp3");
      byte[] arr = new byte[fis.available()];                     //虽然可以拷贝,但是在开发时不建议,有可能会导致内存溢出
      fis.read(arr);
      fos.write(arr);
      fis.close();
      
    • 4,带缓冲区的拷贝

      FileInputStream fis = new FileInputStream("致青春.mp3");       //创建输入流对象,关联致青春.mp3
      BufferedInputStream bis = new BufferedInputStream(fis);     //对fis进行包装,内置一个8192大小的字节数组      
      FileOutputStream fos = new FileOutputStream("copy.mp3");    //创建输出流对象,关联copy.mp3
      BufferedOutputStream bos = new BufferedOutputStream(fos);   //对fos进行包装,内置一个8192大小的字节数组
      
      int b;
      while((b = bis.read()) != -1) {                             //read一次会先将文件上的数据读到缓冲区中,再从缓冲区一个一个的赋值给b
          bos.write(b);                                           //write一次,是将b中的字节数据写到缓冲区,缓冲区写满再一次写到文件上
      }
      
      bis.close();                                                //只需要关掉包装后的即可
      bos.close();
      
  • 5.BufferedInputStream

    • BufferedInputStream内置了一个缓冲区(数组)
    • 从BufferedInputStream中读取一个字节时
    • BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个
    • 程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
    • 直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
  • 6.BufferedOutputStream
    • BufferedOutputStream也内置了一个缓冲区(数组)
    • 程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中
    • 直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里
  • 7.读中文
    • 字节流只读中文有弊端,可能会出现半个中文
    • 解决办法
    • 1,用字符流只读
    • 2,将文件上的所有的字节数据都读到缓冲区中,然后在转换成字符串ByteArrayOutputStream
  • FileInputStream fis = new FileInputStream("bbb.txt");
    byte[] arr = new byte[4];
    int len;
    while((len = fis.read(arr)) != -1) {
        System.out.println(new String(arr,0,len));
    }
    
    fis.close(); 
    
  • 8.写中文
    • 字节流是可以写字符串的
    • 但是必须将字符串转换成字节数组写出去

  • FileOutputStream fos = new FileOutputStream(“bbb.txt”);
    fos.write(“你要减肥,造吗”.getBytes());
    fos.close();
  • 9.finally嵌套
  • 1.6版本及以前的标准的异常处理代码

    FileInputStream fis = null; 
    FileOutputStream fos = null; 
    try {
        fis = new FileInputStream("aaa.txt");
        fos = new FileOutputStream("bbb.txt");
    
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b);
        }
    }finally {
        try {
            if(fis != null) 
                fis.close();
        } finally {
            if(fos != null)
                fos.close();
        }
    }
    
  • 10.try close
  • 1.7版本的标准的异常处理代码

    try(
        FileInputStream fis = new FileInputStream("aaa.txt");
        FileOutputStream fos = new FileOutputStream("bbb.txt");
        MyClose mc = new MyClose();
    ){
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b);
        }
    }
    

三.今日重点

  • 1.拷贝文件
    • a.使用FileInputStream和FileOutputStream, 逐个字节拷贝,效率太低了
    • b.使用FileInputStream和FileOutputStream, 定义一个大数组(length等于文件大小), 一次性拷贝,有可能会内存溢出
    • c.使用FileInputStream和FileOutputStream, 定义一个小数组(例如1024), 多次拷贝
    • d.使用BufferedInputStream和BufferedOutputStream内置的缓冲区, 逐个字节拷贝
  • 2.标准化IO流操作的代码
    • a.finally嵌套
    • b.try close

四.练习

  • 1.从键盘输入接收一个文件路径, 把该文件的内容拷贝到工程中
  • 2.从键盘接收输入, 把键盘输入的数据写到文件, 直到输入quit时退出
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值