问题引入
hello world!,你好,世界!
使用字节输入流,读取以上文件,每次读取1个字节,然后再转换成字符,输出到控制台。
@Test
public void demo1() throws IOException {
FileInputStream fis = new FileInputStream("other\\chinese_input.txt");
int b;
while((b = fis.read()) != -1) {
System.out.print(new String(new byte[]{(byte)b}));
}
fis.close();
}
hello world!������������������
打印到控制台的结果是乱码,因为中文在当前文件中占3个字节(中文占几个字节受文件编码格式的影响),每次读取1个字节,只是读取到了中文的一半,在码表中找不到这一个字节该怎么展示,所以输出到控制台为“?”,
解决这一问题,可以使用内存输出流
内存输出流概述
内存输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据。
常用成员方法
- 创建对象: new ByteArrayOutputStream()
- 写出数据: write(int), write(byte[])
-
演示
/** * FileInputStream读取中文的时候出现了乱码 * * 解决方案 * 1.字符流读取 * 2.ByteArrayOutputStream * @throws IOException */ @Test public void demo2() throws IOException { FileInputStream fis = new FileInputStream("other\\chinese_input.txt"); //在内存中创建了可以增长的内存数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); //将读取到的数据逐个写到内存中 int b; while((b = fis.read()) != -1) { baos.write(b); } //将缓冲区的数据全部获取出来,并赋值给arr数组 byte[] arr = baos.toByteArray(); //new String(arr)与toString()方法的区别是,他可以使用指定字符集将字节转换为字符串 System.out.println(new String(arr)); System.out.println("=========================="); //将缓冲区的内容转换为了字符串,在输出语句中也可以省略调用toString方法 System.out.println(baos.toString()); /** * ByteArrayOutputStream无需关闭流, * 因为它并没有对接硬盘上的文件,而是在内存中开辟了一块区域, * 就像使用集合一样,不使用了,它会被JVM垃圾回收释放。 */ //fis.close(); }hello world!你好,世界! ========================== hello world!你好,世界!
