1.由于字节流操作中文不是很方便,所以Java 提供了转换流。
字符流 = 字节流 + 编码表
编码表:
ASCII表:美国标准信息交换码,用一个字节的7位可以表示
ISO8859-1:拉丁码表。欧洲码表,用一个字节的8位可以表示。
GB2312:中国的中文编码表
GBK:中国的中文编码表升级,融合了更多的中文字符。
GB8030:GBK的取代版本
BIG-5:通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”
Unicode:国际标准码,融合了更多文字。所有文字都用两个字节来表示,Java语言就是用的Unicode
UTF-8:最多用三个字节来表示一个字符,能用一个表示就用一个,不行就两个,实在不行就三个
2.编码 、 解码
String(byte[] bytes, String charsetName) :通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
byte[] getBytes(String charsetName) :使用指定的字符集将此 String 编码为 byte 序列
编码:把看得懂的变成看不懂的
解码:把看不懂的变成看得懂的
编码、解码使用的编码表只有是一样的,才能正确解码出来结果。
3.转换流:把字节流转换为字符流
OutputStreamWriter、InputStreamReader
字符流 = 字节流 + 编码表
(1)OutputStreamWriter:
子类:FileWriter(实际我们经常用的是其子类)
构造方法:
OutputStreamWriter(OutputStream out) :根据默认字符编码把字节流数据转换为字符流。
OutputStreamWriter(OutputStream out, String charsetName) :根据指定字符集编码把字节流数据转换为字符流。
//创建对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"),"GBK") ; //指定GBK编码
//写入数据
osw.write("中国") ;
//释放资源
osw.close() ;
字符流的五种写入方法:
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) :写入字符串的某一部分。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt")) ;
// void write(int c) :写入单个字符。
osw.write("A");
osw.write(97);
//void write(char[] cbuf) :写入字符数组。
char[] c = {'<','b','c','d','>'} ;
osw.write(c);
//abstract void write(char[] cbuf, int off, int len) :写入字符数组的某一部分。
osw.write(c,1,3);
// void write(String str) :写入字符串。
osw.write("12345");
//void write(String str, int off, int len) :写入字符串的某一部分
osw.write("12345", 1, 3);
//osw.flush();
osw.close();
面试题:close()和flush()的区别?
A:close()关闭流对象,但是先刷新一下缓冲区。关闭之后,流对象不可以继续使用。
B:flush()仅仅刷新缓冲区,流对象可以继续使用。
(2)InputStreamReader :
子类:FileReader(实际我们经常用的是其子类)
构造方法:
InputStreamReader(InputStream in) :根据默认字符编码把字节流数据读取为字符流。
InputStreamReader(InputStream in, String charsetName) :根据指定字符集编码把字节流数据读取为字符流。
//创建对象
InputStreamReader isr= new InputStreamReader (new FileInputStream("isr.txt"),"GBK") ; //指定GBK编码
//读取数据
int ch = 0 ;
while((ch = isr.read()) != -1 ){
System.out.print((char) ch) ;
}
//释放资源
isr.close() ;
字符流的两种读取方法:
int read() :读取单个字符
int read(char[] cbuf) : 将字符读入数组
//创建对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("fis.txt")) ;
// //int read() :读取单个字符
// int ch = 0 ;
// while((ch = isr.read()) != -1){
// System.out.print((char)ch);
// }
//int read(char[] cbuf) : 将字符读入数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len = isr.read(chs)) != -1){
System.out.print(new String(chs,0,len));
}
//释放资源
isr.close();
4.字符转换流复制文件
//创建对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("fis.txt")) ;
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fis2.txt")) ;
//读取数据
char[] chs = new char[1024] ;
int len = 0 ;
while((len = isr.read(chs)) != -1){
//写入数据
osw.write(new String(chs,0,len));
}
//释放资源
osw.close();
isr.close();
5.FileReader和FileWriter
由于我们常见的操作都是使用默认编码,所以不指定编码。
而转换流的名字有点长,所以java提供了其子类供我们使用。
其中关系如下:
OutputStreamWriter = FileOutputStream + 编码表(GBK)
FileWriter = OutputStreamWriter +编码表(GBK)
InputStreamReader = FileInputStream + 编码表(GBK)
FileReader = InputStreamReader + 编码表(GBK)
实际应用中我们基本都是用FileReader和FileWriter而不是其父类。其用法和父类一样。
如下使用FileReader和FileWriter来复制文件
//封装资源
FileReader fr = new FileReader("fis.txt") ;
FileWriter fw = new FileWriter("fis2.txt") ;
//读取数据
char[] chs = new char[1024] ;
int len = 0 ;
while( (len = fr.read(chs)) != -1 ){
//写入数据
fw.write(new String( chs , 0 , len ));
}
//释放资源
fr.close();
fw.close();
6.缓冲流:字符流为了高效率读写,提供了对应的字符缓冲流
(1)BufferedWriter:字符缓冲输出流
构造方法:
BufferedWriter(Writer out) :创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz) :创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
bw.write("中国你好");
bw.close();
(2)BufferedReader:字符缓冲输入流
构造方法摘要
BufferedReader(Reader in) :创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) :创建一个使用指定大小输入缓冲区的缓冲字符输入流。
//创建对象
BufferedReader br = new BufferedReader(new FileReader("fis.txt")) ;
//读取数据
char[] chs = new char[1024] ;
int len = 0 ;
while((len = br.read(chs)) != -1){
System.out.print(new String(chs, 0 , len));
}
//释放资源
chs.clone();
(3)字符缓冲流的特殊方法:
BufferedWriter:
public void nextLine() :根据系统来决定输入换行符
BufferedReader:
public void readLine():一次读取一行数据,包含该行内容的字符串但是不包含任何终止符,如果已达文件末尾,则返回null。
因此,以下代码才是我们最常用的代码:
//写入方法
public void write() throws IOException {
//封装资源
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
//写入数据
for (int i = 0; i < 10; i++) {
bw.write("你好Java-" + i);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
//读取方法
public void read() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
String line = null ;
while((line = br.readLine()) != null ){
System.out.println(line);
}
br.close();
}
//复制文件
//封装资源
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt")) ;
//读取数据
String line = null ;
while((line = br.readLine()) != null){
bw.write(line) ;
bw.newLine();
bw.flush() ;
}
//释放资源
bw.close() ;
br.close() ;