提出问题
使用 字符流 读取 GBK 编码的文件,会出现 乱码
准备文件
使用windows自带的文本编辑器,写一段汉字,如下:
哈哈呵呵嘻嘻
保存时指定 GBK 编码,如下图:
代码:
public static void main1(String[] args) {
FileReader fileReader = null;
BufferedReader br = null;
try {
// fileReader = new FileReader("f:/3汉字.txt");
fileReader = new FileReader("f:/4汉字UTF-8.txt");
br = new BufferedReader(fileReader);
// 读取一行
String line = br.readLine();
while(line != null){ // 读取的行不为null,说明后面还有内容,就可以继续读
System.out.println(line);
line = br.readLine();
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(br !=null){
try {
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if(fileReader!=null){ // 先打开的后关闭
try {
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
执行结果是 乱码
解决
使用字节流转字符流,并指定编码,即可解决
说明
InputStreamReader 是从字节流到字符流的桥梁:读取字节,并使用指定的 charset 将其 解码为字符 。
如果不指定字符集,用平台的默认字符集。操作系统默认字符集:
- windows10、linux、macos,默认字符集是
UTF-8 - windows8以前,默认字符集是
GBK
构造方法
创建一个使用默认字符集的InputStreamReader:
InputStreamReader(InputStream in)
创建一个使用给定字符集的InputStreamReader:
InputStreamReader(InputStream in, Charset cs)
创建一个使用命名字符集的InputStreamReader:
InputStreamReader(InputStream in, String charsetName)
易发生错误
调用 read() 方法,可能会发生转换失败
如:读取 含有中文内容的文件,该文件是 UTF-8 编码,也就是说需要 2-3 个字节 才能 转换 成 中文,当 读取1个字节,就开始转换时,就会导致 转换失败
解决
为了使字节有效地转换为字符,可以用 BufferedReader 缓冲流:
String file = "D:\\java\\util\\src\\main\\java\\top\\malaoshi\\util\\MapUtil.java";
FileInputStream fis = new FileInputStream(file);;
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
BufferedReader br = new BufferedReader(isr);
然后用 BufferedReader 的 readLine() 方法读取一行
例子
String file = "D:\\java\\util\\src\\main\\java\\top\\malaoshi\\util\\MapUtil.java";
FileInputStream fis = new FileInputStream(file);;
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
BufferedReader br = new BufferedReader(isr);
String line=null;
while( (line = br.readLine()) != null){
System.out.println(line);
}
//先打开的后关闭
br.close();
isr.close();
fis.close();

