在IDEA中使用文件字符输入流FileReader读取项目中的文本文件时 由于IDEA的默认设置为UTF-8编码 因此没有任何问题
但当读取Windows系统中创建的文本文件时 由于Windows系统的默认是GBK编码 就会出现诸如此类的乱码:����˧��
那么 该如何读取GBK类型的文件呢?
我们需要转换流!
java.io.InputStreamReader
输入转换流是Reader的子类 是从字节流到字符流的桥梁
使用指定的charset(字符集)读取字节 并使用指定的字符集将其解码为字符
它的字符集可以由传入的名称指定 也可以使用默认字符集
在作为字节文件存储在硬盘中的时候 GBK编码以一个中文两个字节存储 UTF-8编码以一个中文三个字节存储
FileReader底层使用的是字节流读取文件 只是内部进行了解码 将字节查询IDE的默认编码表后转换为字符
然而 IDE默认编码表用的是UTF-8 因此 读取的若同为UTF-8编码格式的文件 则无任何问题 直接就能查询出正确的结果
但若读取的是GBK编码格式的文件 则码表对应不上 因而出现乱码
但使用InputStreamReader输入转换流之后则不会出现该问题 因为可以手动指定解码的格式 可指定为GBK 因此就能正确解码了
InputStreamReader(InputStream in)
:创建一个使用默认字符集的字符流
InputStreamReader(InputStream in, String charsetName)
:创建一个指定字符集的字符流
参数:
InputStream in:字节输入流 读取文件中保存的字节
String charsetName:指定的编码表名称
不区分大小写 可以是utf-8 也可以是UTF-8 可以是gbk 也可以是GBK
若不指定 则默认使用UTF-8
public int read() : 从输入流读取一个字符
public int read(char[] cbuf) : 从输入流中读取一些字符 并将它们存储到字符数组中
public void close() :关闭此流并释放与此流相关联的任何系统资源
1、创建InputStreamReader对象 构造方法中传入字节输入流和指定的字节码名称
2、使用InputStreamReader对象中的read()方法读取文件
3、释放资源
注:构造方法中指定的编码表名称须和文件的编码一致 否则会出现乱码
读UTF-8格式:
// 创建InputStreamReader对象 构造方法中传入字节输入流和指定的字节码名称
// InputStreamReader isr=new InputStreamReader(new FileInputStream("F:\\IdeaProjects\\filetest\\utf_8.txt"),"utf-8");
InputStreamReader isr=new InputStreamReader(new FileInputStream("F:\\IdeaProjects\\filetest\\utf_8.txt"));
// 使用InputStreamReader对象中的read()方法读取文件
int len=0;
while ((len=isr.read())!=-1)
{
System.out.print((char)len);
}
// 释放资源
isr.close();
读GBK格式:
// 创建InputStreamReader对象 构造方法中传入字节输入流和指定的字节码名称
InputStreamReader isr=new InputStreamReader(new FileInputStream("F:\\IdeaProjects\\filetest\\gbk.txt"),"gbk");
// 使用InputStreamReader对象中的read()方法读取文件
int len=0;
while ((len=isr.read())!=-1)
{
System.out.print((char)len);
}
// 释放资源
isr.close();
java.io.OutputStreamWriter
输出转换流是Writer的子类 是从字符流到字节流的桥梁
使用指定的charset(字符集)将字符编码为字节
它的字符集可以由传入的名称指定 也可以接受默认字符集
底层用的是FileWriter 因此只能使用IDE的默认码表(即UTF-8)
当转换的时候 会查询编码表 将字符按照默认编码转换为字节
写入到文件中的时候 底层用的是FileOutputStream字节输出流 依次将字节写入到文件中 此时格式为UTF-8
但使用OutputStreamReader输出转换流之后则不会出现该问题 因为可以查询手动指定的编码表
然后使其以GBK格式编码 再用字节输出流将编码后的字节输出到文件中
OutputStreamWriter(OutputStream out)
:创建使用默认编码的OutputStreamWriter
OutputStreamWriter(OutputStream out,String charsetName)
:创建使用指定字符集的OutputStreamWriter
参数:
OutputStream out:字节输出流 可用来写转换之后的字节到文件中
String charsetName:指定的编码表名称
不区分大小写 可以是utf-8 也可以是UTF-8 可以是gbk 也可以是GBK
若不指定 则默认使用UTF-8
void write(int c) 写入单个字符
void write(char[] cbuf) 写入字符数组
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分 off:数组的开始索引 len:写的字符个数
void write(String str) 写入字符串
void write(String str, int off, int len) 写入字符串的某一部分 off:字符串的开始索引 len:写的字符个数
void flush() 刷新该流的缓冲
void close() 关闭此流 但要先刷新它
1、创建OutputStreamWriter对象 构造方法中传递字节输出流和指定的编码表名称
2、使用OutputStreamWriter对象中的write()方法将字符转换为字节存储到缓冲区中(该过程即为编码)
3、使用OutputStreamWriter对象中的flush()方法将内存缓冲区中的字节刷新到文件中(使用字节流写字节)
4、释放资源
写UTF-8格式:
// 创建OutputStreamWriter对象 构造方法中传递字节输出流和指定的编码表名称
// OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("F:\\IdeaProjects\\filetest\\utf_8.txt"),"utf-8");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("F:\\IdeaProjects\\filetest\\utf_8.txt"));
// 使用OutputStreamWriter对象中的write()方法将字符转换为字节存储到缓冲区中
osw.write("我很帅");
// 使用OutputStreamWriter对象中的flush()方法 将内存缓冲区中的字节刷新到文件中(使用字节流写字节)
osw.flush();
// 释放资源
osw.close();
写GBK格式:
// 创建OutputStreamWriter对象 构造方法中传递字节输出流和指定的编码表名称
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("F:\\IdeaProjects\\filetest\\gbk.txt"),"gbk");
// 使用OutputStreamWriter对象中的write()方法将字符转换为字节存储到缓冲区中
osw.write("我非常帅");
// 使用OutputStreamWriter对象中的flush()方法 将内存缓冲区中的字节刷新到文件中(使用字节流写字节)
osw.flush();
// 释放资源
osw.close();