zoukankan      html  css  js  c++  java
  • 详解 字符转换流

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


    @


    字符转换流

    字符转换流 和本人之前在博文《详解 字节输出流 与 字节输入流》所讲解的知识点类似,总共分为两个部分 —— 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("
    ");
            out.write("当我打出?");//一次写入一个字符串
            out.write("
    ");
            out.write("不是我有问题啦啦啦啦阿联",0,5);//一次写入字符串的一部分
            out.write("
    ");
            out.write(new char[]{'而','是'});//一次写入一个字符数组
            out.write("
    ");
            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

  • 相关阅读:
    事以密成,能者低调
    时间过得真快,一晃三年过去了
    读书随记2011111
    Makefile
    ubuntu 7 下 tftp 的配置
    uboot移植到nano2410
    ubuntu 7.04 Feisty Fawn 安装手记之五:安装常用软件
    移植linux2.6.18到arm9
    移植busybox 1.4.2
    UBoot中SMDK2410的NAND Flash驱动。
  • 原文地址:https://www.cnblogs.com/codderYouzg/p/12418577.html
Copyright © 2011-2022 走看看