Java 17 IO流、字节流、字符流

IO流

  • IO流概述:1.IO流用来处理设备之间的数据传输
    2.Java对数据的操作是通过流的方式
    3.Java用于操作流的对象都在IO包中 java.io

  • IO流分类:

    • 按数据流向 站在内存角度:

      输入流 读入数据
      输出流 写出数据

    • 按照数据类型

      字节流:可以读写任何类型的文件 比如音频 视频 文本文件

      字符流:只能读写文本文件

  • 什么情况下使用哪种流?

    如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。如果什么都不知道,就用字节流。

  • IO流基类概述

    • 字节流的抽象基类:

      InputStream ,OutputStream。

    • 字符流的抽象基类:

      Reader , Writer。

    • 注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
      如:InputStream的子类FileInputStream。
      如:Reader的子类FileReader。

字节流
  • FileOutputStream 文件输出流是用于将数据写入 File 或 的输出流。

  • 字节流的继承关系

在这里插入图片描述

FileOutputStream(File file)//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
   FileOutputStream(File file, boolean append)//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

   FileOutputStream(String name)
   //创建一个向具有指定名称的文件中写入数据的输出文件流。
   FileOutputStream(String name, boolean append)
   //创建一个向具有指定 name 的文件中写入数据的输出文件流。
  • 功能
public static void main(String[] args) throws IOException {
   FileOutputStream out = new FileOutputStream("a.txt");
        //一次写入一个字节
        out.write(97); //文本文件通过字符展示,写入97 文件中存入字符a
    byte[] bytes = "1234567890".getBytes();
    out.write(bytes);
    //一次写入字节数组的一部分 0 从字节数组中的那个索引开始 2 写个字节。
    out.write(bytes,0,2);
    //换行符
   // 	  windows下的换行符只用是 \r\n
   //     Linux		\n
   //     Mac		\r
   //是否追加写入,true 就是追加写入,false 就是默认覆盖。
    FileOutputStream out = new FileOutputStream("b.txt",true);
    out.write("123".getBytes());
    out.write("\r\n".getBytes());
    out.write("456".getBytes());
    out.write("\r\n".getBytes());
    out.write("789".getBytes());
    out.write("\r\n".getBytes());
    out.write("123".getBytes());
    out.write("\r\n".getBytes());
    //释放资源
    out.close();
  • 注意事项:
    创建字节输出流对象了做了几件事情 ?
    a : 调用系统资源创建a.txt文件
    b:创建了一个fos对象
    c:把fos对象指向这个文件

    为什么一定要close() ?

    a : 通知系统释放关于管理a.txt文件的资源
    b: 让Io流对象变成垃圾, 等待垃圾回收器对其回收

  • FileInputStream 从文件系统中的某个文件中获得输入字节

    • 构造方法摘要
      FileInputStream(File file);
             // 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
      
      FileInputStream(String name);
             // 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
      //输入流所关联的文件如果不存在,就会报错。
      File file = new File("c.txt");
      file.createNewFile();
      FileInputStream in = new FileInputStream(file);
      //读取文件中的数据
      //一个读取一个字节
      int by = in.read();
      byte[] bytes = new byte[1024];
      //一个读取换一个字节数组 ,返回的是 实际读取到子节个数
      int len = in.read(bytes);
      
    • 复制文件

      public static void main(String[] args) throws IOException {
          //很显然 一次复制一个字节,太慢。
          FileInputStream in = new FileInputStream("C:\\Users\\gaga\\Desktop\\末班车.mp3");
          FileOutputStream out = new FileOutputStream("C:\\Users\\gaga\\Desktop\\A.mp3");
          int by=0;
          while ((by=in.read())!=-1){
              out.write(by);
              out.flush();
          }
          in.close();
          out.close();
          System.out.println("复制完成");
      }
      
      public static void main(String[] args) throws IOException {
          //推荐使用一次复制一个字节来做
          //很显然 一次复制一个字节,太慢。
          FileInputStream in = new FileInputStream("C:\\Users\\gaga\\Desktop\\末班车.mp3");
          FileOutputStream out = new FileOutputStream("C:\\Users\\gaga\\Desktop\\b.mp3");
          //定义一个数组来充当缓冲区。
          byte[] bytes = new byte[1024 * 8];
          //定义一个变量,来记录实际读取到的字节个数
          int len=0;
          while ((len=in.read(bytes))!=-1){
              out.write(bytes,0,len);
              out.flush();
          }
          in.close();
          out.close();
          System.out.println("复制完成");
      
      }
      
  • BufferedOutputStream

    • 缓冲思想

      ​ 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流。

    • BufferedOutputStream的构造方法

      • BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
      • BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
  • BufferedInputStream

    ​ BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持mark和reset方法的能力。在创建BufferedInputStream时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark操作记录输入流中的某个点,reset操作是的在从包含的输入流中获取新字节之前,再次读取字最后一次mark操作后读取的所有字节。

    • BufferedInputStream的构造方法

      • BufferedInputStream(InputStream in)

        创建一个BufferedInputStream并保存其参数,即输入流in,一遍将来使用。

      • BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的BufferedInputStream并保存其参数,及输入流in,以便将来使用。

字符流
  • 字符流= 字节流+编码表,只能对文本文件进行读写。

    编码:把字符串转换为字节数组。

    解码:把字节数组转换为字符串。

    乱码:编解码没有采用同一张码表。

    getBytes(); 采用平台默认的码表进行编码。

  • 字符流的继承关系

在这里插入图片描述

  • //getBytes("GBK"); 自己指定编码表
    byte[] bytes = "张三李四王五".getBytes("UTF-8");
    for (byte aByte : bytes) {
        System.out.println(aByte);
    }
    //new String(bytes); 采用平台默认的码表进行解码。
            //String s = new String(bytes, "GBK"); 指定码表进行解码
            String s = new String(bytes,"GBK");
            System.out.println(s);
    
  • OutputStreamWrite 是字符流向字节流的桥梁;

    ​ 可使用指定的码表将要写入流中的媳妇编码成字节。他使用的字符集可以由名称指定货显式给定,否则将接受平台默认的字符集。

    • OutputStreamWriter的构造方法
      • OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。输出流所关联的文件,如果不存在,会自动创建。
  • InputStreamReader 是字节流通向字符流的桥梁

    ​ 它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

    ​ 输入流,所关联的文件,如果不存在,就会报错。如果读取不到有效字符,就返回-1.我们使用-1来判断文件是否读取完。

    • InputStreamReader 的构造方法
      • InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
      • InputStreamReader(InputStream in, String charsetName)
        创建使用指定字符集的 InputStreamReader。
    • 读取文件
    public static void main(String[] args) throws IOException {
        InputStreamReader reader = new InputStreamReader(new FileInputStream("c.txt"));
        char[] chars = new char[10];
        //一次读取一个字符数组,返回值,返回的是读取到的有效的字符个数
          // int len = reader.read(chars);
        int len = reader.read(chars,0,3);
        System.out.println(len);
        for (char aChar : chars) {
            System.out.println(aChar);
        }
    
        reader.close();
    }
    
    • 文件的复制

      public static void main(String[] args) throws IOException {
          //一次读取一个字符,写一个字符来复制文本文件
          InputStreamReader in = new InputStreamReader(new FileInputStream("MyTest.java"));
          OutputStreamWriter out= new OutputStreamWriter(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\MyTest.java"));
          int ch=0;
          while ((ch=in.read())!=-1){
              out.write(ch);
              out.flush();
      }
          in.close();
          out.close();
      
      }
      -------------------------
      public static void main(String[] args) throws IOException {
              //一次读写一个字符数组,来复制
              //一次读取一个字符,写一个字符来复制文本文件
              InputStreamReader in = new InputStreamReader(new FileInputStream("MyTest.java"));
              OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\MyTest.java"));
      
              char[] chars = new char[1000];
              int len=0;
              while ((len=in.read(chars))!=-1){
                  // System.out.println("循环次数");
                  out.write(chars,0,len);
                  out.flush();
              }
              in.close();
              out.close();
      
          }
      
  • BufferedWriter

    ​ 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

    • BufferedWriter 的构造方法

      • BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
      • BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
    • 高效字符流特有的方法

      void newLine() 写入一个行分隔符。

      String readLine() 读取一个文本行。

      public static void main(String[] args) throws IOException {
          BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
          BufferedWriter bfw = new BufferedWriter(new FileWriter("b.txt"));
          String str=null;
          if((str=bfr.readLine())!=null){
              bfw.write(str);
              bfw.newLine();
              bfw.flush();
          }
          bfr.close();
          bfw.close();
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值