Java学习笔记(二十一):IO流之字符流
由于字节流操作中文不是特别方便,所以java就提供了字符流。字符流 = 字节流 + 编码表。
一、编解码
编码就是把字符串转换成字节数组,方法如下:
public byte[] getBytes();使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
public byte[] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
String str="我爱你";
//按照平台默认的码表进行编码
byte[] bytes = str.getBytes(); //编码
//按照GBK来变得码
byte[] gbks = str.getBytes("UTF-8");
二、解码
解码就是把字节数组转换成字符串,方法如下:
public String(byte[] bytes): 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
public String(byte[] bytes, String charsetName) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
//按照平台默认的码表进行解码
String s = new String(bytes);
//按照GBK来解码:
String s1 = new String(gbks, "GBK");
转换流OutputStreamWriter
OutputStreamWriter 是字符流通向字节流的桥梁,可使用指定的码表 将要写入流中的字符编码成字节。
它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
构造方法:
OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
//输出流所关联的文件,如果不存在会自动创建
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));
OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
//可以指定码表
OutputStreamWriter out2 = new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK");
写数据的方法如下,注意:使用OutputStreamWriter写入数据一定要刷新才会显示。
public void write(int c) 写一个字符
public void write(char[] cbuf) 写一个字符数组
public void write(char[] cbuf,int off,int len) 写一个字符数组的 一部分
public void write(String str) 写一个字符串
public void write(String str,int off,int len) 写一个字符串的一部分
追加写入和异常捕获
OutputStreamWriter同FileOutputStream,每次写入的编译都会重新覆盖文件的内容。要想每次写入追加内容,也就是每次编译不仅保存原数据,同时写入新数据,就需要进行追加写入操作。因为异常捕获的方法同FileOutputStream,因此一同展示。
public static void main(String[] args) {
//流的异常处理
OutputStreamWriter out = null;
try {
//追加处理的方式是在FileOutputStream中添加true
out = new OutputStreamWriter(new FileOutputStream("c.txt", true));
out.write("你看乱码了没有");
out.write("\r\n");
out.write('好');
out.write("\r\n");
//一次写入一个字符数组
out.write(new char[]{'a', 'b', 'c', '哈', '哈'});
out.write("\r\n");
//一次写入字符串的一部分 从字符串的2索引出开始,写3个字符
out.write("写入字符串的一部分", 2, 3);
out.write("\r\n");
//一次写入字符数组的一部分,从0索引处开始 写3个字符
out.write(new char[]{'a', 'b', 'c', '哈', '哈'}, 0, 3);
out.write("\r\n");
//字符流,记得要刷新
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
转换流InputStreamReader
InputStreamReader 是字节流通向字符流的桥梁,它使用指定的 码表 读取字节并将其解码为字符。
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
构造方法:
InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
//输入流所关联的文件,如果不存在就报错
InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
//指定码表
InputStreamReader in2 = new InputStreamReader(new FileInputStream("e.txt"), "GBK");
读数据方法:
public int read() :一次读取一个字符
public int read(char[] cbuf) :一次读取一个字符数组 如果没有读到 返回-1
字符流复制文本文件
public static void main(String[] args) throws IOException {
//使用字符流来复制文本文件
InputStreamReader reader = new InputStreamReader(new FileInputStream("MyTest.java"));
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Desktop\\bbb.java"));
//一次读取一个字符,写一个字符。来复制文件,效率低 不推荐
//推荐一次读写一个字符数组来复制
char[] chars = new char[2000]; //定义一个字符数组,充当缓冲区
int len=0;//用来记录实际读取到的字符个数
int count=1;
while ((len=reader.read(chars))!=-1){
System.out.println("循环次数"+(count++));
writer.write(chars,0,len);
writer.flush();
}
reader.close();
writer.close();
System.out.println("复制完成");
}
FileWriter和FileReader
转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以为了简化我们的书写,转换流提供了对应的子类FileWriter和FileReader。其使用方法大致与InputStreamReader和OutputStreamWriter完全一致,但是也有需要注意的地方:
- FileReader和FileWriter的构造方法与其父类InputStreamReader和OutputStreamWriter不同,FileReader和FileWriter构造方法中的参数可以是File类型和String类型,而不是其父类要求的字节流;
- FileReader和FileWriter用于写入字符流。要写入原始字节流,就需要使用 FileOutputStream和FileInputStream。
高效字符流
高效字符流有以下两种:
- BufferedWriter:用于写出数据 ,是高效的字符输出流;
- BufferedReader:用于读取数据 ,是高效的字符输入流。
构造方法:
BufferedWriter:
public BufferedWriter(Writer w)
BufferedReader:
public BufferedReader(Reader e)
字符缓冲流中提供了以下两个特殊方法:
BufferedWriter: public void newLine():根据系统来决定换行符,是具有系统兼容性的换行符。
BufferedReader: public String readLine():一次读取一行数据。以换行符为标记,读到换行符就换行,没读到数据返回null。包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null。
具体使用方法在使用字符缓冲流复制文本文件中体现:
public static void main(String[] args) throws IOException {
//使用高效的字符流。读取一行,写入一行来复制文件,逐行复制。
BufferedReader reader = new BufferedReader(new FileReader("MyTest.java"));
BufferedWriter writer = new BufferedWriter(new FileWriter("hehe.java"));
//循环的进行读取一行,写入一行
//一行一行读取,读取不到返回的是null
String line=null; //定义一个变量,来记录每次读取到的一行文本
while ((line=reader.readLine())!=null){
writer.write(line);
//writer.write("\r\n");
writer.newLine();
writer.flush();
}
writer.close();
reader.close();
}