刚刚学习JavaIO流, 可能会很乱, IO流怎么这么多东西啊, 如果对JavaIO体系不熟悉,请查阅先的博客.
https://blog.youkuaiyun.com/huangchongwen/article/details/80866984
今天复习的主题是 -- JavaIO流的编解码, 字符流与字节流区别!
一 : 字节流、字符流读写
案例1 : 字节流读取中文.
private static void readFileByInputStream2(String path) throws IOException {
FileInputStream fis = new FileInputStream(path);
int len = 0;
while ((len = fis.read()) != -1) {
System.out.print((char) len);
}}
}
}
运行结果我们都知道, 含有中文很可能出现乱码! 原因是什么?字节流本身不会自动编解码, 而使用字符流则没有问题, 字符流具有自动编解码效果。
二: 编码与解码
String 类型-》byte 就是编码过程,
byte-》String 类型 解码过程! 假如我们还是想要使用字节流读写中文, 那可以手动为字节流编码与解码!
private static void writeFileByOutputStream(String path, String content)
throws IOException {
FileOutputStream fos = new FileOutputStream(path);
// 把字符串进行编码操作
byte[] bytes = content.getBytes("utf-8");
// 内容通过字节流写入到文件中。
fos.write(bytes);
fos.close();
}
private static void readFileByInputStream(String path) throws IOException {
FileInputStream fis = new FileInputStream(path);
int len = 0;
byte[] buffer = new byte[1024];
while ((len = fis.read(buffer)) != -1) {
// 二进制解码,使用系统默认编码
System.out.println(new String(buffer, 0, len,"utf-8"));
}
}
我们手动为字节流编解码, 同样可以读写中文! 刚刚学习IO流, 经常听说: 字符流=字节流+编码表。反过来理解一下, 字节流+自动编码=字符流。字符流可以自动编码(使用系统默认的码表), 字节流可以手动编码实现和字符流类似的功能! 如果不能理解这个, 那来看看先代码。
os=new FileOutputStream(file);
String str=new String("hello gay!");
// os.write(str); 不编码--错误
os.write(str.getBytes());// 按照默认的GBK编码String c="我是中国人!";
w=new FileWriter(filepath,true);
w.write(c);//不需要编码都正确
三 字符流的弊端
字节流和字符流那个更加强大? 应该是字节流. 字符流可以做到的字节流都可以, 但是字节流做到的字符流不一定可以做到。比如拷贝媒体文件(图片、视频等)。
拷贝文件使用字节流而不使用字符流,因为字符流读文件涉及到解码,会先解码,写文件的时候又涉及到编码,这些操作多余,而且读和写的码表不对应还容易引发问题。一句话解释就是:媒体文件的二进制数据是纯二进制,不是有意义的字符,所以码表无法转换。
四 转换流
InputStreamReader 是字节流通向字符流的桥梁,是字节流->字符流 ,不能逆向。很显然可以包装我们的字节流,自动的完成节流编码和解码的工作。
注意: 码表不对应,发现都会出现乱码的问题.
public class Demo4 {
public static void main(String[] args) throws IOException {
File file = new File("c:\\a.txt");
File fileGBK = new File("c:\\gbk.txt");
File fileUTF = new File("c:\\utf.txt");
// 默认编码
testReadFile(file);
// 传入gbk编码文件,使用gbk解码
testReadFile(fileGBK, "gbk");
// 传入utf-8文件,使用utf-8解码
testReadFile(fileUTF, "utf-8");
}
// 该方法中nputStreamReader使用系统默认编码读取文件.
private static void testReadFile(File file) throws
IOException {
FileInputStream fis = new FileInputStream(file);
InputStreamReader ins = new InputStreamReader(fis);
int len = 0;
while ((len = ins.read()) != -1) {
System.out.print((char) len);
}
ins.close();
fis.close();
}
// 该方法使用指定编码读取文件
private static void testReadFile(File file, String encod)
throws IOException {
FileInputStream fis = new FileInputStream(file);
InputStreamReader ins = new InputStreamReader(fis, encod);
int len = 0;
while ((len = ins.read()) != -1) {
System.out.print((char) len);
}
ins.close();
}
}