【面试真题拆解04】Java字节流、字符流

四季读书网 1 0
【面试真题拆解04】Java字节流、字符流

之前面试一家小公司的时候被问到过,现在整理一下。

Java IO流的分类

Java IO流主要从两个维度分类:

分类维度
分类结果
说明
数据流向
输入流
从磁盘/网络/内存数据到程序
输出流
从程序数据到磁盘/网络/内存
处理单元
字节流
以字节为单位处理数据,是万能流
字符流
以字符为单位处理数据,专门处理文本

字节流

什么是字节流?

计算机里所有数据(图片、视频、音频、文本、PDF)本质上都是字节(0和1的组合),所以字节流是万能流,可以处理任何类型的数据。

字节流的核心类

字节流的抽象基类是 InputStream(输入流)和 OutputStream(输出流),开发中最常用的是它们的子类:

类名
作用
FileInputStream
从文件中读取字节
FileOutputStream
向文件中写入字节
BufferedInputStream
带缓冲的字节输入流,提升读性能
BufferedOutputStream
带缓冲的字节输出流,提升写性能

举个例子

字节流典型的应用——复制非文本文件(图片、视频、PDF)

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;publicclassByteStreamExample{publicstaticvoidmain(String[] args){// 源文件路径(一张图片)        String srcPath = "C:/test/photo.jpg";// 目标文件路径        String destPath = "C:/test/photo_copy.jpg";// 用try-with-resources自动关闭流,避免内存泄漏try (// 1. 创建文件字节输入流:从源文件读字节            FileInputStream fis = new FileInputStream(srcPath);// 2. 创建文件字节输出流:向目标文件写字节            FileOutputStream fos = new FileOutputStream(destPath)        ) {// 3. 定义一个字节数组作为缓冲区(一次读1024字节,即1KB,提升性能)byte[] buffer = newbyte[1024];int len; // 记录每次实际读到的字节数// 4. 循环读写:fis.read(buffer)返回-1表示读到文件末尾while ((len = fis.read(buffer)) != -1) {// 只写实际读到的len个字节,避免最后一次写多余的空字节                fos.write(buffer, 0, len);            }            System.out.println("图片复制成功!");        } catch (IOException e) {            e.printStackTrace();        }    }}

字符流

什么是字符流?

字符流是专门处理文本数据的流,它以【字符】为单位处理数据,内部会自动处理编码转换(比如把UTF-8编码的字节转成Java的char字符)。

为什么不用字节流处理文本?

因为中文、日文等非ASCII字符占多个字节(比如UTF-8编码的中文占3个字节)。

如果用字节流读,可能会把一个汉字的3个字节截断,从而导致乱码

而字符流会自动识别编码,按字符读取,不会乱码。

字符流的核心类

字符流的抽象基类是 Reader(输入流)和 Writer(输出流),开发中最常用的是它们的子类:

类名
作用
FileReader
从文件中读取字符
FileWriter
向文件中写入字符
BufferedReader
带缓冲的字符输入流
BufferedWriter
带缓冲的字符输出流
InputStreamReader
转换流:字节流转字符流
OutputStreamWriter
转换流:字符流转字节流

举个例子

BufferedReaderreadLine()方法可以按行读取文本,非常方便。

import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.nio.charset.StandardCharsets;publicclassCharacterStreamExample{publicstaticvoidmain(String[] args){        String filePath = "C:/test/中文文章.txt";// 用转换流InputStreamReader,显式指定UTF-8编码,避免乱码try (// 1. 先创建字节输入流            FileInputStream fis = new FileInputStream(filePath);// 2. 用转换流把字节流转成字符流,显式指定UTF-8编码            InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);// 3. 用缓冲流包装,提升性能,且有readLine()方法            BufferedReader br = new BufferedReader(isr)        ) {            String line;int lineNum = 1;// readLine()返回null表示读到文件末尾while ((line = br.readLine()) != null) {                System.out.println("第" + lineNum + "行:" + line);                lineNum++;            }        } catch (IOException e) {            e.printStackTrace();        }    }}

抱歉,评论功能暂时关闭!