字符流的本质:字节流 + 编码表
基于某个编码表. 每个字符对应这一个整数值(编码值), 计算机存的就是这个整数值
ASCII:美国标准信息交换码。
用一个字节的7位可以表示。0000 0000 - 0111 1111
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示。 0000 0000 - 1111 1111
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。2个字节表示一个中文
GB18030:GBK的取代版本
BIG-5码 :通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码
Unicode:国际标准码,融合了多种文字。
UTF-8:可变长度来表示一个字符。
UTF-16:jvm使用的编码表,用2个字节来编解码
常用的:
默认的编码表
获取编码表:
System.out.println(Charset.defaultCharset());
eg:
// 编码
String s = "你好";
// getBytes()
// 使用平台的默认字符集将此 String 编码为 byte 序列,
// 并将结果存储到一个新的 byte 数组中。
byte[] bytes = s.getBytes();
System.out.println(Arrays.toString(bytes));
// getBytes(String charsetName)
// 使用指定的字符集将此 String 编码为 byte 序列,
// 并将结果存储到一个新的 byte 数组中。
byte[] gbks = s.getBytes("GBK");
System.out.println(Arrays.toString(gbks));
// 解码
// 利用String的构造方法
// String(byte[] bytes)
// 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String s1 = new String(bytes);
System.out.println(s1);
// 利用指定的字符集
// String(bytes[] b, String charsetName)
String s2 = new String(gbks,"GBK");
System.out.println(s2);
乱码问题
写入字符流的抽象类
继承关系:
成员方法:
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset
将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
构造方法:
OutputStreamWriter(OutputStream out)
// 创建使用默认字符编码的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
// 创建使用指定字符集的 OutputStreamWriter。
成员方法:
write
方法
eg:
// 1. 创建输出流对象
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));
// 2. write
// 2.1 write(int c) 写单个字符
out.write(97);
out.write(System.lineSeparator());
// 2.2 write(char[] c) 写字符数组
String s = "hello world";
char[] charArray = s.toCharArray();
out.write(charArray);
out.write(System.lineSeparator());
// 2.3 write(char[] c, int off ,int len)
out.write(charArray,0,3);
// 2.4 write(String s)
out.write(s);
out.write(System.lineSeparator());
// 2.5 write(String s, int off ,int len)
out.write(s,0,3);
// 3. flush
out.flush();
// 4. close
out.close();
用来写入字符文件的便捷类
简化流是转化流的直接子类
构造方法:
FileWriter(File file)
// 根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append)
// 根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(String fileName)
// 根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
// 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
构造方法:
5个write
其中:3个跟字符相关的,2个跟字符串相关的
eg:
/*
使用简化流写数据FileWriter
*/
// 1. 创建输出流对象
FileWriter fw = new FileWriter("a.txt");
// 2. write
fw.write("hello world");
// 3. flush
fw.flush();
// 4. close
fw.close();
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了
构造方法:
BufferedWriter(Writer out)
// 创建一个使用默认大小输出缓冲区的缓冲字符输出流。默认缓冲区大小是16KB
BufferedWriter(Writer out, int sz)
// 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。缓冲区大小size
成员方法:
5个常规的write
1个独有的方法
newLine() 写入一个行分隔符。
eg:
/*
使用缓冲流进行读写数据
*/
// 1. 创建输出流对象
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")));
BufferedWriter bw1 =
new BufferedWriter(new FileWriter("a.txt"));
// 2. write
bw.newLine();
bw.write("hello hi");
// 3. flush
bw.flush();
// 4. close
bw.close();
bw1.close();
用于读取字符流的抽象类
成员方法:
read()
// 返回值为int
// 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),
// 如果已到达流的末尾,则返回 -1 用readData 读取到的字符值
read(char[] cbuf)
// 返回值为int
// 将字符读入数组。读取的字符数,
// 如果已到达流的末尾,则返回 -1 用readCount表示 读取到的字符的个数
read(char[] cbuf, int off, int len)
// 返回值为int,并且是抽象方法
// 将字符读入数组的某一部分。
构造方法:
InputStreamReader(InputStream in)
// 创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName)
// 创建使用指定字符集的 InputStreamReader。
成员方法:
3个read
方法
read()
read(char[] c)
read(char[] c ,int off, int len)
eg:
// 1. 创建输入流对象
InputStreamReader in = new InputStreamReader(new FileInputStream("a.txt"));
// 2.1 read() 读取单个字符
int readData = in.read();
System.out.println(((char) readData));
// 2.2 read(char[] c) 批量读取
char[] chars = new char[1024];
int readCount = in.read(chars);
String s = new String(chars, 0, readCount);
System.out.println(s);
// 3. close
in.close();
构造方法:
FileReader(File file)
// 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(String fileName)
// 在给定从中读取数据的文件名的情况下创建一个新 FileReader。
成员方法:
3个read
eg:
/*
使用FileReader读取数据
*/
// 1. 创建输入流对象
FileReader fr = new FileReader("a.txt");
// 2. read
char[] chars = new char[1024];
int readCount = fr.read(chars);
System.out.println(new String(chars,0,readCount));
// 3. close
fr.close();
转换流VS简化流
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了
构造方法:
BufferedReader(Reader in)
// 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)
// 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
3个常规read
1个独有的方法(readLine() 读取一个文本行。如果已到达流末尾,则返回 null)
eg:
/*
使用缓冲的字符流读写数据
*/
// 1. 创建输入流对象
BufferedReader bufferedReader =
new BufferedReader(new FileReader("a.txt"));
// 2. read
char[] chars = new char[1024];
int readCount = bufferedReader.read(chars);
System.out.println(new String(chars,0,readCount));
// 3. close
bufferedReader.close();
eg:
构造字符流的Utils包
// 单字符流进行复制
public static void copy3(Reader reader, Writer writer) throws IOException{
int readData;
while((readData = reader.read()) != -1){
writer.write(readData);
}
}
// 字符数组方式进行复制
public static void copy4(Reader reader, Writer writer) throws IOException{
int readCount;
char[] chars = new char[1024];
while((readCount = reader.read(chars)) != -1){
writer.write(chars,0,readCount);
}
}