字符流
有了字节流为什么需要学习字符流?
1.字节流处理 换行 等字符不方便
2.字节流在 处理 文本文件的时候,如果做了人为的转换,可能会出现乱码
3.字节流不能够处理编码问题
4.针对读取一行或者读取一部分的操作不方便
编码和解码
编码: 将字符/字符数组/字符串 转换成 二进制
解码: 将二进制 转换成 字符/字符数组/字符串
编码表: 字符和十进制数值对应的一张表而已
产生乱码原因:
1.服务器,客户端,数据库,文件系统之间的编码和解码使用的编码表不一致 (沟通)
2.人为在使用字节流读取的过程中做了转换 (使用字符流解决)
编码解码的三种情况
1.处理字符情况
2.处理字符串情况
3.处理文本文件情况
public class CharIODemo01 {
public static void main(String[] args) throws UnsupportedEncodingException {
// 获取当前系统支持的编码
/*SortedMap<String, Charset> charsetMap = Charset.availableCharsets();
for(String key : charsetMap.keySet()) {
Charset value = charsetMap.get(key);
System.out.println(key + "=" + value);
}*/
// 1.处理字符情况
char ch = 'a';
// 编码
System.out.println((int)ch);
int i = 97;
// 解码
System.out.println((char)97);
// 2.处理字符串情况
String s = "中国Hello";
// 编码
byte[] bys = s.getBytes("UTF-8");
System.out.println(Arrays.toString(bys)); // [-42, -48, -71, -6, 72, 101, 108, 108, 111]
// 解码
String ss = new String(bys, "UTF-8");
System.out.println(ss);
}
}
3.处理文本文件情况
利用的是字符流的一个转换流
字符输出流
需求:使用字符流向文本里写入“HelloWorld”。
Writer(抽象类,不能直接使用,选择子类)
OutputStreamWriter(转换流,是字符流通向字节流的桥梁,可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认字符集编码。)
构造方法
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的字符输出转换流
OutputStreamWriter(OutputStream out, Charset cs) 创建使用cs字符集的字符输出转换流
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建使用enc字符集编码器的
OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的
Writer append(char c)
将指定字符添加到此 writer。
Writer append(CharSequence csq)
将指定字符序列添加到此 writer。
Writer append(CharSequence csq, int start, int end)
将指定字符序列的子序列添加到此 writer.Appendable。
abstract void close()
关闭此流,但要先刷新它。
abstract void flush()
刷新该流的缓冲。
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str)
写入字符串。
void write(String str, int off, int len)
写入字符串的某一部分。
转换流的功能
1.具备读写字符和字符数组和字符串的能力
2.具备将字节流转换成字符流的能力
3.能够处理文件编码
public class CharIODemo02 {
public static void main(String[] args) throws Exception {
String s = "HelloWorld";
Writer w = new OutputStreamWriter(new FileOutputStream("out.txt"),"utf-8");
w.write(s);
w.append("good");
w.append("morning");
w.append('a');
w.write(new char[] {'a','b','c'});
w.write("中国你好");
w.flush();
w.close();
}
}
转换字符输入流
int read()
读取单个字符。
int read(char[] cbuf)
将字符读入数组。
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。
public class CharIODemo03 {
public static void main(String[] args) throws Exception {
Reader r = new InputStreamReader(new FileInputStream("out.txt"), "UTF-8");
/*int ch = r.read();
System.out.println((char)ch);
ch = r.read();
System.out.println((char)ch);
ch = r.read();
System.out.println((char)ch);
ch = r.read();
System.out.println((char)ch);
ch = r.read();
System.out.println((char)ch);
ch = r.read();
System.out.println((char)ch);*/
/*int ch = 0;
while ((ch = r.read()) != -1) {
System.out.print((char)ch);
}*/
char[] chs = new char[5];
int len = 0;
/*len = r.read(chs);
System.out.println(new String(chs, 0, len));
len = r.read(chs);
System.out.println(new String(chs, 0, len));*/
while ((len = r.read(chs)) != -1) {
System.out.println(new String(chs, 0, len));
}
}
}
转换流拷贝文件
public class CharIODemo04 {
public static void main(String[] args) throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("IODemo06.java"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("demo.txt"));
int len = 0;
char[] chs = new char[1024];
while ((len = isr.read(chs)) != -1) {
osw.write(chs, 0, len);
osw.flush();
}
isr.close();
osw.close();
}
}