1. 编码表
常见编码表:GBK,utf-8
编码:文字字串-》数字字节流:"string text".getBytes ----> byte[] bArr
解码:数字字节流-》文字字串:byte[] bArr ----> new String(bArr)
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个字符,也可以读取字符数组
说明:
① InputStreamReader构造方法也有单参和双参,当不填编码格式时,采用系统的默认编码格式;如果填写的编码格式,则会按照编码格式来识别FileInputStream读取到的字节
②这里可以一个字节一个字节读取,也可以多个字节读取,多个字节的读取形式效率更高
③只需要close外层InputStreamReader的对象,内层有系统close
3.3 转换流父类、子类的关系
OutputStreamWriter的子类FileWriter
InputStreamReader的子类FileReader
在使用时,如果都用默认的编码格式,则采用子类
如果需要转换编码格式,则必须用父类