413. Java 文件操作基础 - 用装饰器模式实现 Sonnet 的 GZIP 序列化

413. Java 文件操作基础 - 用装饰器模式实现 Sonnet 的 GZIP 序列化

✍️ 写入压缩的单个 Sonnet

各位,我们已经能够把 Sonnet 从文本文件中读出来了,那么接下来要做的事情是:把一个 Sonnet 压缩存储

为什么要压缩呢?💡

  • 因为 原始文本文件可能很大(莎士比亚的十四行诗全集有 154 首),如果我们以后要存储、传输,压缩可以大大节省空间。
  • Java 提供了内置的 GZIP 压缩工具类,我们不需要自己写压缩算法,只要用好 API 就可以了。

🎯 压缩思路

我们希望把一个 Sonnet 的所有行写入一个压缩后的二进制文件。Java 的 I/O 提供了一个 GZIPOutputStream 类来帮我们完成压缩。

具体思路:

  1. 创建一个 ByteArrayOutputStream —— 用来存放最终压缩后的二进制数据。
  2. GZIPOutputStream 包装它 —— 实现压缩功能。
  3. 再用 PrintWriter 包装 —— 方便逐行写入字符串(因为 PrintWriter 提供 println() 方法,非常适合写文本)。
  4. 最终返回一个 byte[] —— 就是压缩后的字节数组,可以保存到文件或传输给别人。

✅ 在 Sonnet 类中新增方法

class Sonnet {
    private List<String> lines = new ArrayList<>();

    public void add(String line) {
        lines.add(line);
    }

    // 压缩成字节数组的方法
    byte[] getCompressedBytes() throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzos = new GZIPOutputStream(bos);
             PrintWriter printWriter = new PrintWriter(gzos)) {

            for (String line : lines) {
                printWriter.println(line);
            }
        }
        // 返回压缩后的字节数组
        return bos.toByteArray();
    }
}

🔍 方法解析

  • ByteArrayOutputStream bos
    → 相当于一个“内存文件”,所有压缩数据最终都在这里。
  • GZIPOutputStream gzos = new GZIPOutputStream(bos)
    → 把数据写进去时会自动压缩。
  • PrintWriter printWriter = new PrintWriter(gzos)
    → 提供 println(line) 方法,写起来很方便。
  • try-with-resources
    → 即使这里没有外部文件,依然有必要:它能自动调用 close(),帮我们刷新(flush)缓冲区,确保所有内容都被写入压缩流。

📌 使用示例

假设我们有一个 Sonnet 对象:

public class Main {
    public static void main(String[] args) throws IOException {
        Sonnet sonnet = new Sonnet();
        sonnet.add("Shall I compare thee to a summer's day?");
        sonnet.add("Thou art more lovely and more temperate:");
        sonnet.add("Rough winds do shake the darling buds of May,");
        sonnet.add("And summer's lease hath all too short a date:");

        // 获取压缩后的字节数组
        byte[] compressed = sonnet.getCompressedBytes();

        // 写入文件
        Files.write(Path.of("sonnet1.gz"), compressed);

        System.out.println("✅ Sonnet 已压缩并写入 sonnet1.gz 文件");
    }
}

运行结果:

  • 在项目目录下会生成一个 sonnet1.gz 文件。
  • 你可以用 gzip -d sonnet1.gz(Linux/Mac)或 7-Zip(Windows)解压缩,里面就是你写的那几行诗。

🚀 总结

  1. 压缩文件存储在字节数组中,方便后续操作(写入文件/网络传输)。
  2. 装饰器模式ByteArrayOutputStream → GZIPOutputStream → PrintWriter,逐层增加功能。
  3. try-with-resources 不仅用于外部文件资源,也能确保缓冲区正确刷新。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容