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

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


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

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

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

推荐阅读更多精彩内容