Java 字节流与字符流

核心概念

在Java I/O体系中,流(Stream)是数据传输的抽象。根据处理数据单位的不同,它们被分为两大类:

  1. 字节流:用于处理二进制数据,以字节(8位)为基本单位。

  2. 字符流:用于处理文本数据,以字符(16位Unicode)为基本单位。


1. 字节流

  • 核心抽象类:InputStream 和 OutputStream

  • 处理单位:字节(byte,8位)。

  • 用途:可以用来处理任何类型的数据,因为所有文件(图片、视频、可执行程序、文本文件等)在底层都是以字节形式存储的。

  • 特点:

    • 原始数据:它不关心数据的含义,只是原样读取和写入字节。

    • 通用性强:万能工具,什么都能处理。

    • 处理文本可能出错:如果用它来读取文本(尤其是包含多字节字符的,如中文),可能会因为编码问题导致乱码。

常见子类举例:

  • FileInputStream / FileOutputStream:用于读写文件。

  • ByteArrayInputStream / ByteArrayOutputStream:用于在内存中读写数据。

  • BufferedInputStream / BufferedOutputStream:提供缓冲功能,提高读写效率。

简单示例(读取一个文件的所有字节):

try (FileInputStream fis = new FileInputStream("image.jpg")) {
    int byteData;
    while ((byteData = fis.read()) != -1) {
        // 处理每一个字节 byteData
    }
} catch (IOException e) {
    e.printStackTrace();
}

2. 字符流

  • 核心抽象类:Reader 和 Writer

  • 处理单位:字符(char,16位)。

  • 用途:专门为处理文本数据而设计。它能自动处理字符编码(如UTF-8, GBK等),确保正确地将字节序列转换为字符,反之亦然。

  • 特点:

    • 高层抽象:它理解“字符”的概念,屏蔽了底层字节编码的复杂性。

    • 自动编码转换:在读取时,它将字节根据指定的字符集解码成字符;在写入时,它将字符编码成字节。默认使用系统的字符编码,但可以指定。

    • 处理文本更方便、安全:是处理纯文本文件的首选。

常见子类举例:

  • InputStreamReader / OutputStreamWriter:桥梁作用,可以将字节流转换为字符流,并指定字符集。

  • FileReader / FileWriter:用于读写文本文件(是InputStreamReaderFileInputStream的组合的便捷类)。

  • BufferedReader / BufferedWriter:提供缓冲功能,并且BufferedReaderreadLine()方法,可以方便地按行读取。

简单示例(按行读取一个文本文件):

try (BufferedReader br = new BufferedReader(new FileReader("text.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        // 处理每一行文本 line
    }
} catch (IOException e) {
    e.printStackTrace();
}

核心区别与联系

特性字节流字符流
基本单位 字节(8位) 字符(16位Unicode)
处理数据类型 所有二进制数据(如图片、音频、视频等) 文本数据
核心抽象类 InputStreamOutputStream ReaderWriter
是否处理编码 否,直接操作字节 是,依赖字符编码进行转换
性能 处理非文本数据效率高 处理文本数据效率高且安全
关系 底层基础 基于字节流构建,通过InputStreamReader/OutputStreamWriter进行转换

如何选择?

  1. 处理非文本文件(如图片、压缩包、PDF):使用字节流。

  2. 处理文本文件(如.txt, .java, .html):优先使用字符流,特别是BufferedReaderBufferedWriter,因为它们能避免乱码问题,并且提供了更方便的API(如readLine)。

 
 
 
posted @ 2025-11-17 02:00  YukiRinLL  阅读(5)  评论(0)    收藏  举报