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

1. 编码表

常见编码表:GBK,utf-8

19b130a9a7ed

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

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

19b130a9a7ed

查看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写字符到文件

19b130a9a7ed

这里说明代码中三处地方:①:构造方法如果不填编码格式,则为该系统的默认编码格式,在英文linux上默认是utf-8

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

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

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

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

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

3.2 InputstreamReader

这个类的原理和使用方式和3.1中的OutputStreamWriter刚好是相反的java.io.InputStreamReader 继承Reader

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

读取方法

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

19b130a9a7ed

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

19b130a9a7ed

使用给定gbk编码格式读取gbk文件,打印显示中文

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

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

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

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

OutputStreamWriter的子类FileWriter

InputStreamReader的子类FileReader

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值