406. Java 文件操作基础 - 字符与二进制流

文章目录

  • [406. Java 文件操作基础 - 字符与二进制流](#406. Java 文件操作基础 - 字符与二进制流)
    • [1️⃣ 概述](#1️⃣ 概述)
    • [2️⃣ Writing Characters using `OutputStreamWriter`](#2️⃣ Writing Characters using OutputStreamWriter)
      • [🔑 讲解](#🔑 讲解)
    • [3️⃣ Reading Characters using `InputStreamReader`](#3️⃣ Reading Characters using InputStreamReader)
      • [🔑 讲解](#🔑 讲解)
    • [4️⃣ 小结](#4️⃣ 小结)

406. Java 文件操作基础 - 字符与二进制流

1️⃣ 概述

在 Java I/O API 中,类分为两大类:

  • 字符流(Reader / Writer):处理文本数据
  • 字节流(InputStream / OutputStream):处理二进制数据

虽然字符流通常用于文本文件,但在应用程序中也常需要将字符写入二进制文件。

Java 提供了两个关键类来实现这一点:

  • InputStreamReader:从字节流读取字符
  • OutputStreamWriter:向字节流写入字符

这两个类都是 装饰器(Decorator)模式 的例子,它们依赖底层的字节流,并提供字符处理功能。


2️⃣ Writing Characters using OutputStreamWriter

java 复制代码
import java.nio.file.*;
import java.io.*;

public class WriteCharToBinary {
    public static void main(String[] args) throws IOException {
        String message = "From fairest creatures we desire increase,\n" +
                "That thereby beauty's rose might never die,\n" +
                "But as the riper should by time decease\n" +
                "His tender heir might bear his memory:\n" +
                "But thou, contracted to thine own bright eyes,\n" +
                "Feed'st thy light's flame with self-substantial fuel,\n" +
                "Making a famine where abundance lies,\n" +
                "Thyself thy foe, to thy sweet self too cruel.\n" +
                "Thou that art now the world's fresh ornament,\n" +
                "And only herald to the gaudy spring,\n" +
                "Within thine own bud buriest thy content,\n" +
                "And, tender churl, mak'st waste in niggardly.\n" +
                "Pity the world, or else this glutton be,\n" +
                "To eat the world's due, by the grave and thee.";

        Path path = Paths.get("sonnet.txt");

        try (OutputStream outputStream = Files.newOutputStream(path);
             OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) {

            writer.write(message);

        } catch (IOException e) {
            e.printStackTrace();
        }

        long size = Files.size(path);
        System.out.println("size = " + size);
    }
}

🔑 讲解

  1. OutputStreamWriter 装饰 OutputStream :
    • 将字节流转换为字符流
    • 可以指定字符集(Charset)
  2. try-with-resources 保证关闭顺序 :
    • 输出流和字符写入器都会在退出时自动 flush() 和 close()
    • 避免因缓冲区未刷新导致文件内容丢失
  3. 效果 :
    • 会在 files/sonnet.txt 创建一个文本文件
    • 控制台输出文件大小,例如:size = 609

3️⃣ Reading Characters using InputStreamReader

java 复制代码
import java.nio.file.*;
import java.io.*;
import java.util.stream.*;
import java.util.*;

public class ReadCharFromBinary {
    public static void main(String[] args) {
        Path path = Path.of("files/sonnet.txt");
        String sonnet = null;

        try (InputStream inputStream = Files.newInputStream(path);
             InputStreamReader reader = new InputStreamReader(inputStream);
             BufferedReader bufferedReader = new BufferedReader(reader);
             Stream<String> lines = bufferedReader.lines()) {

            // 使用流将每行文本合并为一个完整字符串
            sonnet = lines.collect(Collectors.joining("\n"));

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("sonnet = \n" + sonnet);
    }
}

🔑 讲解

  1. InputStreamReader 装饰 InputStream :
    • 将字节流转换为字符流
  2. BufferedReader 装饰 InputStreamReader :
    • 提供按行读取功能
    • 内部使用缓冲,提高读取性能
  3. 使用 Stream API :
    • BufferedReader.lines() 返回 Stream<String>
    • 结合 Collectors.joining("\n") 可以轻松把所有行合并
  4. try-with-resources :
    • 自动关闭 InputStream、Reader、BufferedReader 和 Stream
    • 保证资源安全
  5. 效果 :
    • 控制台输出完整文本内容,与写入文件的内容一致

4️⃣ 小结

  • OutputStreamWriter / InputStreamReader 是处理字符与字节混合 I/O 的关键工具
  • 装饰者模式 :
    • OutputStreamReader / InputStreamReader → 装饰字节流
    • BufferedReader → 进一步装饰,提供额外功能(按行读取、流式操作)
  • try-with-resources 确保所有流和资源正确关闭
  • 字符流与字节流组合 非常灵活:
    • 可用于写文本到二进制文件
    • 可用于读取二进制文件中的字符
相关推荐
tongyiixiaohuang16 分钟前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
中科三方21 分钟前
IPv6检测常见问题:AAAA记录检测不通过是什么原因?
开发语言·php
卡提西亚30 分钟前
FastAPI基础入门
python·fastapi
fanruitian1 小时前
python 机器学习 ML LinearRegression KNN KMeans
python·机器学习·kmeans
鱼宵1 小时前
取集合第一个元素,Java 为什么要写三种写法?
java·windows·python·java21
卷无止境1 小时前
给AI装上一双眼睛:快速构建代码验证器的思路与落地方案
后端·python
学长毕设1 小时前
基于SpringBoot的餐厅管理系统-附源码
java·spring boot·后端
沫璃染墨1 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
维克兜率天1 小时前
【维克】指数调整:哪些股票会被“强制买入“?
人工智能·python·算法
刚入门的大一新生1 小时前
Linux-线程互斥
java·开发语言