详解 字符转换流

(请观看本人博文——《详解 字符流》


@


字符转换流

字符转换流 和本人之前在博文《详解 字节输出流 与 字节输入流》所讲解的知识点类似,总共分为两个部分 —— OutputStreamWriter(字符转换输出流)InputStreamReader(字符转换输入流)
那么,现在,本人就来讲解下这两个类:


OutputStreamWriter:

(输出流)

本人先来介绍下InputStreamReader类:
定义

OutputStreamWriter 是字符流通向字节流的桥梁:
可使用指定的 charset要写入流中的字符编码成字节
它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集

构造方法

  • OutputStreamWriter(OutputStream out):
    根据默认编码(GBK)把字节流的数据转换为字符流
  • OutputStreamWriter(OutputStream out,String charsetName):
    根据指定编码把字节流数据转换为字符流
  • OutputStreamWriter(OutputStream out, Charset cs)
    创建使用给定字符集的 OutputStreamWriter
  • OutputStreamWriter(OutputStream out, CharsetEncoder enc)
    创建使用给定字符集编码器的 OutputStreamWriter

需要强调的一点是:

  • 这个类只能用于操作文本文件
  • 当我们所表示的文件不存在时,会自动帮我们创建一个相应的文件
  • 这个类相当于包装了字节流的OutputStream类,所以若是我们想实现文本文件内容的追加,就要传递以参数append为true所构建出来的OutputStream对象

这个类的 常用API 也是write():

  • public void write(int c)
    一个字符
  • public void write(char[] cbuf)
    一个字符数组
  • public void write(char[] cbuf,int off,int len)
    一个字符数组的 一部分
  • public void write(String str)
    一个字符串
  • public void write(String str,int off,int len)
    一个字符串的一部分

本人现在来讲解下这个类的write()方法的底层实现过程:

每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器
写入底层输出流之前得到的这些字节将在缓冲区中累积
可以指定此缓冲区的大小, 不过,默认的缓冲区对多数用途来说已足够大。
(注意:传递给 write() 方法的 字符 没有缓冲)

那么,本人来展示下这些API的使用:

package edu.youzg.about_io.about_file.core;

import java.io.*;

public class Test {

    public static void main(String[] args) throws IOException {
        OutputStreamWriter out = out=new OutputStreamWriter(new FileOutputStream("test.txt",true),"utf-8");
        out.write('?'); //一次写一个字符
        out.write("\r\n");
        out.write("当我打出?");//一次写入一个字符串
        out.write("\r\n");
        out.write("不是我有问题啦啦啦啦阿联",0,5);//一次写入字符串的一部分
        out.write("\r\n");
        out.write(new char[]{'而','是'});//一次写入一个字符数组
        out.write("\r\n");
        out.write(new char[]{'c', '你', '有', '问', '题', '?', '!', 'a'},1,4);//一次写入一个字符数组的一部分
        //释放资源
        out.close();

    }

}

本人现来展示下运行前的目录:
在这里插入图片描述
现在,本人展示下运行后的目录 以及 创建出来的文件的内容:
在这里插入图片描述
那么,现在,本人来讲下InputStreamReader类:


InputStreamReader:

(输入流)

本人先来介绍下InputStreamReader类:
定义

InputStreamReader 是字节流通向字符流的桥梁
它使用指定的 charset ,读取字节将其解码为字符
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集

现在,本人来展示下这个类的构造方法
构造方法:

  • InputStreamReader(InputStream in)
    创建一个使用默认字符集的 InputStreamReader
  • InputStreamReader(InputStream in, Charset cs)
    创建使用给定字符集的 InputStreamReader
  • InputStreamReader(InputStream in, CharsetDecoder dec)
    创建使用给定字符集解码器的 InputStreamReader
  • InputStreamReader(InputStream in, String charsetName)
    创建使用指定字符集的 InputStreamReader

本人要强调的一点是:

构造InputStreamReader对象时,所关联的文件 如果不存在,就会报错

这个类的 常用API 也是read():

  • public int read()
    一次读取一个字符
    返回值为该字符 的ASCII码值
    如果没有读到 ,则返回-1
  • public int read(char[] cbuf)
    一次读取一个字符数组
    如果没有读到 ,则返回-1
  • public int read(char[] cbuf, int offset, int length)
    将字符读入数组中的某一部分
    如果没有读到 ,则返回-1

现在本人来讲解下此类read()方法的底层实现

每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节
(例:在UTF-8编码下,一个汉字占3个字节,当读取汉字字符时,就要读取3个字节)

那么,本人来展示下这些API的使用:

package edu.youzg.about_io.about_file.core;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test {

    public static void main(String[] args) throws IOException {
        FileReader in = new FileReader("test.txt");

        int ch = in.read(); //一次读取一个字符
        System.out.println(ch); //那个字符的ASCII码值

        char[] chars = new char[3];//字符数组,充当缓冲区
        int len = in.read(chars); //返回值,是实际读取到的字符个数
        System.out.println(len);

        String s = String.valueOf(chars);
        System.out.println(s);

        chars = new char[6];//字符数组,充当缓冲区
        len = in.read(chars, 0, 3); //一次读取3个字符,装入缓冲区中
        System.out.println(len);
        s = String.valueOf(chars, 0, len);
        System.out.println(s);

        //释放资源
        in.close();
    }

}

那么,本人来展示下运行结果:
在这里插入图片描述
(换行符在utf-8编码下也算2个字符,即:"/r/n")


那么,现在,本人来利用这两个类,实现下文件的复制操作

我们当然可以一个字节一个字符地读取并写入,但是在前面的知识点讲解中,我们发现,还是每次读入一个数组(充当 缓冲区),那样去完成复制操作,效率会更高,所以,本人就不展示如何一个字符一个字符地复制了

package edu.youzg.about_io.about_file.core;

import java.io.*;

public class Test {

    public static void main(String[] args) throws IOException {
        InputStreamReader in = new InputStreamReader(new FileInputStream("test.txt"));
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("copyView1.txt"));
        char[] chars = new char[1000];
        int len = 0;//读取到有效字符个数
        while ((len=in.read(chars)) != -1){
            out.write(chars,0,len);
            out.flush();//字符流记得刷新一下
        }

        //释放资源
        in.close();
        out.close();
    }

}

那么,现在本人来展示下 生成的文件的内容
在这里插入图片描述
可以看出,本人的代码完成了文件的复制操作!

(本人《详解 字节流 与 字符流》博文链接:https:////www.cnblogs.com/codderYouzg/p/12418532.html
(本人 I/O流总集篇 博文链接:https:////www.cnblogs.com/codderYouzg/p/12418404.html

posted @ 2020-03-05 09:53  在下右转,有何贵干  阅读(317)  评论(0编辑  收藏  举报