美文网首页
Java之IO(三)转换流:Writer/Reader接口

Java之IO(三)转换流:Writer/Reader接口

作者: 如果仲有听日 | 来源:发表于2018-08-27 13:50 被阅读0次

    1. 编码表

    常见编码表:GBK,utf-8

    编码:文字字串-》数字字节流:"string text".getBytes ----> byte[] bArr

    解码:数字字节流-》文字字串:byte[] bArr ----> new String(bArr)

    查看linux系统默认编码格式

    2. FileWriter、FileReader类

    2.1 FileWriter类

    超类:java.io.Writer 接口,需要重写Writer中的抽象方法

    局限:只能写文本文件,只能写字符流,且write()之后需要flush()字符缓冲

                不能修改其编码格式,只能是默认的GBK编码方式

    好处:提供了写入String的write()重载方法,写入中文非常方便

    write重载方法:

        void write(int c)

        void write(char[] charBuf)

        void write(char[] cbuf, int off, int len)

        void write(String str)

    public static void fWriterDemo() throws IOException{

        FileWriter fw = new FileWriter("/kluter/temp/fw.txt");

        fw.write(110);

        fw.write(0x0d);

        fw.write(0x0a);

        fw.flush();

        char[] cArr = {'a', 'B', 'c', 'D', 'e', '\n'};

        fw.write(cArr);

        fw.flush();

        fw.write(cArr, 2, 3);

        fw.flush();

        fw.write("Test String\n");

        fw.flush();

        fw.close();

    }

    特别注意,字符输出流写入文件需要做flush()

    2.2 FileReader

    超类:java.io.Reader 接口,需要重写Reader中的抽象方法

    局限:只能读取文本文件,只能读字符流,且read()之后需要

    没有String的都区功能,对文本的字符读取无法界定

    不能修改其编码格式,只能是默认的GBK编码方式

    好处:读取中文非常方便

    read()重载方法:

        int read() 读一个字符

        int read(char[] charBuf)

        int read(char[] cbuf, int off, int len)

    public static void fReaderDemo() throws IOException{

        FileReader fr = new FileReader("/kluter/temp/fw.txt");

        int ret = 0;

        // while((ret = fr.read()) != -1){

        // out.print((char)ret);

        // }

        // out.print("**************************");

        //

        // fr.reset();

        ret = 0;

        char[] cbuf = new char[10];

        String s = null;

        while((ret = fr.read(cbuf)) != -1){

            s = new String(cbuf, 0, ret);

            out.print(s);

        }

        fr.close();

    }

    2.3 用FileWriter、FilerReader类实现文本文件拷贝

    略,参考:https://www.jianshu.com/p/bf3fb779b742 中的3.2

    用buffer的形式拷贝效率高,也需要考虑IOexception

    2.4 flush() 与 close()的区别

    flush和close方法都有立即将字符写入文件的功能,区别是:

    flush()之后还可以继续write(),而close则不行

    3. OutputStreamWriter、InputStreamReader

    由于InputStream和OutputStream体系中的类,以及FileWriter和FileReader都是处理字符的

    现在引入两个新的类来处理字符转换为字节,用于不同编码间的转换

    3.1 OutputStreamWriter

    转换流

        java.io.OutputStreamWriter 继承Writer接口

        就是一个字符输出流,写文本文件

        write()重载方法,同样有字符参数、字符数组、以及字符串

        字符流通向字节流的桥梁,可以将字符流转字节流:

             (我试过可以用FileWriter写中文、韩语等也能成功,最开始不清楚为什么这里要做转换。最后发现FileWriter是OutputStreamWriter的子类,FileWriter更简单,但是不能改变编码表(只能用系统默认的),例如字符是中文的时候,编码表用GBK更节约空间,GBK是2个字节存储的,而FileWriter在英文linux上默认使用utf-8是3个字节存储的)

            例如中文的“你好”转换为utf-8,“你好是字符”,需要转换为gbk的2x5字节。OutputStreamWriter的作用就是将“你好”字符去查询编码表(例如可以查询utf8、GBK等等)转换成字节形式(utf8、GBK表示),之后再用字节输出流(目前只学过FileOutputStream)将转换后的字节写入文件


    3.1.1 构造方法

    OutputStreamWriter(OutputStream out) 

            //接口的多态应用,接收所有字节输出流

    OutputStreamWriter(OutputStream out, Charset cs) 

            //不常用

    OutputStreamWriter(OutputStream out, CharsetEncoder enc)

            //不常用

    OutputStreamWriter(OutputStream out, String charsetName) 

            //charsetName常见有:GBK、utf-8,大小写不限

    3.1.2 用OutputStreamWriter写字符到文件

    这里说明代码中三处地方:

        ①:构造方法如果不填编码格式,则为该系统的默认编码格式,在英文linux上默认是utf-8

        如果填写了编码格式,大小写不敏感

        ②:写入的字符来决定采用哪种编码格式,如果只有中文,则用GBK(2个字节表示一个汉字)能节约更多空间

        如果有多种语言,则utf-8能全部涵盖

        ③:这里只需要close外层的OutputStreamWriter的对象,内层的FileOutputStream也就自动关闭了

        ④:这段测试代码的含义是将字符“你好是字符”去查询gbk编码表后转换成字节表示,在用FileOutputStream以字符流的形式一个字节一个字节写入文件

    3.2 InputstreamReader

    这个类的原理和使用方式和3.1中的OutputStreamWriter刚好是相反的

    java.io.InputStreamReader 继承Reader

    字符输入流,读取文本文件,将字节流转字符流

    读取方法

        read()重载方法,能够读取1个字符,也可以读取字符数组

    使用默认utf-8格式读取gbk文件,打印显示乱码 使用给定gbk编码格式读取gbk文件,打印显示中文

    说明:

    ① InputStreamReader构造方法也有单参和双参,当不填编码格式时,采用系统的默认编码格式;如果填写的编码格式,则会按照编码格式来识别FileInputStream读取到的字节

    ②这里可以一个字节一个字节读取,也可以多个字节读取,多个字节的读取形式效率更高

    ③只需要close外层InputStreamReader的对象,内层有系统close

    3.3 转换流父类、子类的关系

    OutputStreamWriter的子类FileWriter

    InputStreamReader的子类FileReader

        在使用时,如果都用默认的编码格式,则采用子类

        如果需要转换编码格式,则必须用父类

    相关文章

      网友评论

          本文标题:Java之IO(三)转换流:Writer/Reader接口

          本文链接:https://www.haomeiwen.com/subject/azvziftx.html