Jakartase_IO流_ — 字节流和字符流的区别(壹)

一、流的概念

  • 1.1、程序中所有的数据都是以流的方式进行传输或保存的
  • 1.2、程序需要取数据的时候要使用输入流读取数据,而当程序需要将一些数据保存()到磁盘的时候,就要使用输出流完成。
  • 1.3切记:程序是内,文件…是外

二、流的超类

2.1、字节流的超类:InputStream、OutputStream

  • 作用:处理字节、二进制对象。(其实可用于任何类型的对象,但它不能直接处理Unicode字符)
  • 操作对象:字节流处理单元为1个字节,操作字节和字节数组

2.2、字符流的超类: Reader、Writer

  • 作用: 直接处理字符、字符串。
  • 操作对象:处理的单元为2个字节的Unicode字符
  • 拓展:字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的

2.3、用途推荐

  • 音频文件、图片、歌曲,就用字节流好点
  • 关系到中文(文本)的,用字符流好点

2.4、前言:

其实前言放在这里,笔者认为是不合适的,之前的铺垫只是方便读者快读进入状态

  • 字节流和字符流的关系:
  • 字节流不足:实际开发中很多的数据是文本,字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,于是提出了字符流的概念。
  • 字符流的诞生:字符流按虚拟机的encode处理,也就是通过InputStreamReader,OutputStreamWriter进行字符集的转化

    • 转化(注:初学者可以不看该转化知识,如果想了解原理,该段是有帮助的):

      • InputStreamReader:用于将一个字节流中的字节解码成字符,其构造函数
        InputStreamReader isr = new InputStreamReader(InputStream in)的参数是一个InputStream对象 / System.in,用 对象.read(char[] data),的方式获取内容
      • OutputStreamWriter:用于将写入的字符编码成字节后写入一个字节流,其构造函数(之一)
        OutputStreamWriter osw = new OutputStreamWriter(OutputStream out)是一个OutputStream对象,通常用对象.write(String str)的方式写到 对象绑定的输出流上。
      • 二者都是处理流(包装流、非结点流)—不可直接操作数据!。由上可知二者底层分别是通过byte[]和String来关联它们对应的流对象!

三、字节流与字符流的区别

3.1、操作文件时的区别:

  • 字节流:在操作时不会用到缓冲区(内存),是直接对文件本身进行操作的
  • 字符流:在操作时则使用了缓冲区,通过缓冲区再操作文件。

3.2、存在形式区别:

  • 在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成

四、分析与优化

  • 分析:

    • 对于3.1中的第一点:如果一个程序频繁对一个资源进行IO操作,效率会非常低
  • 优化:

    • 此时,通过缓冲区,先把需要操作的数据暂时放入内存中,以后直接从内存中读取数据,则可以避免多次的IO操作,提高效率。下面是部分代码:

          /*(1)对于视频、图片等文件的加缓冲优化*/
          byte[] fileToByteArray (String filePath){
              File des = new File(filePath);
              FileInputStream fis = new FileInputStream(des);
              ByteArrayOutputStream bios = new ByteArrayOutputStream();
              
              byte[] datas = new byte[1024];     //缓冲容器:提高效率`
              int len = -1;
              while ((len = fis.read(datas)) != -1){
                  bios.write(datas, 0, len); 
                 //把字节数组datas的内容 写入到 字节数组输出流 中--分段写入
              }
              bios.flush();  //强制将缓冲区中的数据写入输出流,并清空缓冲区
              return bios.toByteArray();  
          }
          /*(2)对于纯文本文件的加缓冲优化:*/
             //BufferedReader,内部其实维护一个缓冲字符数组
              String tempStr = "";
              try (FileReader fr = new FileReader("a.txt");
                   FileWriter fw = new FileWriter("b.txt");
                   BufferedWriter bw = new BufferedWriter(fw);
                   BufferedReader br = new BufferedReader(fr)){   //包装:
      
                   while ((tempStr = br.readLine()) != null){
                      //将读取的"一行"字符串写入文件中
                      bw.write(tempStr);
                      //写入下一行的时候,先换行
                      bw.newLine();
                  }
              }
              catch (IOException e){
                  e.printStackTrace();
              }

附:笔者并没有把规范的代码展示出来,只是把与本文相关的核心代码展示给了大家大家有兴趣可以自行补充。内容其实不多,加多几个try,catch语句即可! 希望作者的文章希望可以被您采纳,我们一起学习,共同进步!

    原文作者:Shonan
    原文地址: https://segmentfault.com/a/1190000019840875
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞