- 先来看一段看似没问题的代码
这是一个使用utf-8编码的文本内容,下面使用输入流读取文件内容,打印到控制台。
FileInputStream is = new FileInputStream("C:\\Users\\Administrator\\Desktop\\char.txt");
byte[] bytes = new byte[1024];
int read = is.read(bytes);
while (read != -1){
System.out.println(new String(bytes,0,read));
read = is.read(bytes);
}
is.close();
- 运行结果:
这看似没有问题的运行,实则潜藏着巨大隐患。
utf-8编码在存储中文字符的时候,一个中文字符会分配3或4个字节。那我整个文件有5个字符,最大也就只占20个字节,我创建了一个1024字节的数组,那肯定是一次性就能读完的,没有问题。但当我把字节数组的长度该为5时,此时,只能一次读取5个字节,那么将这5个字节的内容,在用utf-8编码读取的时候就会发生乱码问题。
-
将数组大小设置为5后读取。
-
ByteArrayOutputStream 解决上述问题
FileInputStream is = new FileInputStream("C:\\Users\\Administrator\\Desktop\\char.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1];
int read = is.read(bytes);
while (read != -1){
baos.write(bytes,0,read); //内部会自动扩容
read = is.read(bytes);
}
System.out.println(new String(baos.toByteArray()));
baos.close();
is.close();
创建一个ByteArrayOutputStream 对象,使用字节数组读取输入流内容时,将数组里面的字节数据写入到该对象中,该对象内部也维护了一个字节数据,并且会自动扩容。那么当读取完毕时,我们再一次性将该对象内部维护的这个字节数据按照指定的编码转为字符串即可。
-
运行结果
-
修改文件内容编码再测试
此时需要在字节数组转字符串时指定编码
运行正常!