怎么把输出字节流转成输出字符流,说出步骤

一、IO概述
  • 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据读出来继续使用呢?其实要把数据持久化存储,就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U盘等)上。
  • 当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
  • 当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
  • 因此我们把这种输入和输出动作称为IO操作。
二、IO分类
  • 按流的方向不同
    输入流和输出流


  • 按处理数据的单位不同
    字节流和字符流


  • java.io包中有两大继承体系
    以byte处理为主的Stream类,他们的命名方式是XXXStream
    以字符处理为主的Reader / Writer类,他们的命名方式XXXReader或XXXWriter
  • InputStream、OutputStream、Reader、Writer这四个类,是这两大继承体系的父类
三、字节流
  • 1.字节输出流OutputStream

OutputStream此抽象类,是表示输出字节流的所有类的超类。操作的数据都是字节,定义了输出字节流的基本共性功能方法。
输出流中定义都是写write方法,如下图:


  • 1.1FileOutputStream类

OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。
FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流。

  • 构造方法


  • 1.2 FileOutputStream类写入数据到文件中
  • 将数据写到文件中,代码演示:
  public static void main(String[] args) throws IOException {
      //需求:将数据写入到文件中。
      //创建存储数据的文件。
      File file = new File("c:\\file.txt");
      //创建一个用于操作文件的字节输出流对象。一创建就必须明确数据>存储目的地。
      //输出流目的是文件,会自动创建。如果文件存在,则覆盖。
      FileOutputStream fos = new FileOutputStream(file);
      //调用父类中的write方法。
      byte[] data = "abcde".getBytes();
      fos.write(data);
      //关闭流资源。
      fos.close();
  }
}
  • 2.字节输入流InputStream

前面的学习,我们可以把内存中的数据写出到文件中,那如何想把内存中的数据读到内存中,我们通过InputStream可以实现。InputStream此抽象类,是表示字节输入流的所有类的超类。定义了字节输入流的基本共性功能方法。


  • int read():读取一个字节并返回,没有字节返回-1.
  • int read(byte[]): 读取一定量的字节数,并存储到字节数组中,返回读取到的字节数。
  • 2.1 FileInputStream类

InputStream有很多子类,其中子类FileInputStream可用来读取文件内容。
FileInputStream 从文件系统中的某个文件中获得输入字节。

  • 构造方法


  • 2.2 FileInputStream类读取数据read方法
  • 在读取文件中的数据时,调用read方法,实现从文件中读取数据



    从文件中读取数据,代码演示:

  public static void main(String[] args) throws IOException {
      File file = new File("c:\\file.txt");
      //创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取>流和数据源相关联。
      FileInputStream fis = new FileInputStream(file);
      //读取数据。使用 read();一次读一个字节。
      int ch = 0;
      while((ch=fis.read())!=-1){
          System.out.pr       }intln("ch="+(char)ch);

      // 关闭资源。
      fis.close();
  }
}
  • 2.3 读取数据read(byte[])方法

在读取文件中的数据时,调用read方法,每次只能读取一个,太麻烦了,于是我们可以定义数组作为临时的存储容器,这时可以调用重载的read方法,一次可以读取多个字符


  public static void main(String[] args) throws IOException {
      /*
       * 演示第二个读取方法, read(byte[]);
       */
      File file = new File("c:\\file.txt");
      // 创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取>流和数据源相关联。
      FileInputStream fis = new FileInputStream(file);        
      //创建一个字节数组。
      byte[] buf = new byte[1024];//长度可以定义成1024的整数倍。      
      int len = 0;
      while((len=fis.read(buf))!=-1){
          System.out.println(new String(buf,0,len));
      }
      fis.close();
  }
}
二、字符流

经过前面的学习,我们基本掌握的文件的读写操作,在操作过程中字节流可以操作所有数据,可是当我们操作的文件中有中文字符,并且需要对中文字符做出处理时怎么办呢?

  • 1字符输入流Reader

API中给我们已经提供了读取相应字符的功能流对象,Reader,读取字符流的抽象超类。


  • read():读取单个字符并返回
  • read(char[]):将数据读取到数组中,并返回读取的个数。
  • 1.1FileReader类

查阅FileInputStream的API,发现FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
打开FileReader的API介绍。用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的

  • 构造方法


  • 1.2 FileReader读取包含中文的文件
    public static void main(String[] args) throws IOException {
        //给文件中写中文
        writeCNText();
        //读取文件中的中文
        readCNText();
    }   
    //读取中文
    public static void readCNText() throws IOException {
        FileReader fr = new FileReader("D:\\test\\cn.txt");
        int ch = 0;
        while((ch = fr.read())!=-1){
            //输出的字符对应的编码值
            System.out.println(ch);
            //输出字符本身
            System.out.println((char)ch);
        }
    }
    //写中文
    public static void writeCNText() throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
        fos.write("哈哈".getBytes());
        fos.close();
    }
}
  • 2.字符输出流Writer

既然有专门用于读取字符的流对象,那么肯定也有写的字符流对象,查阅API,发现有一个Writer类,Writer是写入字符流的抽象类。其中描述了相应的写的动作。


  • 2.1 FileWriter写入中文到文件中

查阅FileOutputStream的API,发现FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用 FileWriter。
打开FileWriter的API介绍。用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。

  • 构造方法


  • 2.2 FileWriter写入中文到文件中

写入字符到文件中,先进行流的刷新,再进行流的关闭。

  public static void main(String[] args) throws IOException {
      //演示FileWriter 用于操作文件的便捷类。
      FileWriter fw = new FileWriter("d:\\text\\fw.txt");
      fw.write("你好谢谢再见");//这些文字都要先编码。都写入到了流的缓>冲区中。
      fw.flush();
      fw.close();
  }
}
三、转换流
  • 1.OutputStreamWriter类

查阅OutputStreamWriter的API介绍,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。
代码演示

public static void writeCN() throws Exception {
      //创建与文件关联的字节输出流对象
      FileOutputStream fos = new FileOutputStream("c:\\cn8.txt");
      //创建可以把字符转成字节的转换流对象,并指定编码
      OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
      //调用转换流,把文字写出去,其实是写到转换流的缓冲区中
      osw.write("你好");//写入缓冲区。
      osw.close();
  }

OutputStreamWriter流对象,它到底如何把字符转成字节输出的呢?
其实在OutputStreamWriter流中维护自己的缓冲区,当我们调用OutputStreamWriter对象的write方法时,会拿着字符到指定的码表中进行查询,把查到的字符编码值转成字节数存放到OutputStreamWriter缓冲区中。然后再调用刷新功能,或者关闭流,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。

  • 2.InputStreamReader类

查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

  • 代码演示
  public static void main(String[] args) throws IOException {
      //演示字节转字符流的转换流
      readCN();
  }
  public static void readCN() throws IOException{
      //创建读取文件的字节流对象
      InputStream in = new FileInputStream("c:\\cn8.txt");
      //创建转换流对象 
      //InputStreamReader isr = new InputStreamReader(in);
     //这样创建对象,会用本地默认码表读取,将会发生错误解码的错误
       InputStreamReader isr = new InputStreamReader(in,"utf-8");
      //使用转换流去读字节流中的字节
      int ch = 0;
      while((ch = isr.read())!=-1){
          System.out.println((char)ch);
      }
      //关闭流
      isr.close();
  }
}

注意:在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容