news 2026/5/23 8:19:58

414. Java 文件操作基础 - 批量压缩与索引:将154首十四行诗高效存储为带目录的二进制文件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
414. Java 文件操作基础 - 批量压缩与索引:将154首十四行诗高效存储为带目录的二进制文件

文章目录

  • 414. Java 文件操作基础 - 批量压缩与索引:将154首十四行诗高效存储为带目录的二进制文件
  • 📚 写入所有 Sonnet
    • 🎯 核心思路
    • ✅ 示例代码
    • 🔍 代码解析
    • 📌 使用示例
    • 🚀 总结

414. Java 文件操作基础 - 批量压缩与索引:将154首十四行诗高效存储为带目录的二进制文件

📚 写入所有 Sonnet

前面我们已经学会了如何压缩单个 Sonnet。但是莎士比亚总共有154 首 Sonnet,我们需要把它们都写到一个二进制文件里,方便后续统一存储和读取。

问题是:如果把所有 Sonnet 压缩后直接拼接到一个文件里,后续怎么知道每一首的位置(offset)长度(length)呢?
👉 答案是:我们需要额外存储一个“目录表”,告诉程序每首诗的起始位置和长度。


🎯 核心思路

最终生成的文件结构如下:

-----------------------------------|Numberof sonnets(int)||Offset[0](int)||Length[0](int)||Offset[1](int)||Length[1](int)||...||Offset[n-1](int)||Length[n-1](int)|-----------------------------------|Compressedsonnets bytes array|-----------------------------------
  • Number of sonnets→ 一共有多少首
  • Offset, Length→ 每首 Sonnet 在压缩字节数组中的位置和大小
  • Compressed data→ 154 首 Sonnet 的压缩内容

💡 注意:这里的 offset 是相对于压缩字节数组的起始位置(不是整个文件开头)。如果想让它相对于整个文件,需要加上 header 的大小:4 + 2*4*numberOfSonnets


✅ 示例代码

intnumberOfSonnets=sonnets.size();PathsonnetsFile=Path.of("files/sonnets.bin");try(varsonnetFile=Files.newOutputStream(sonnetsFile);vardos=newDataOutputStream(sonnetFile)){List<Integer>offsets=newArrayList<>();List<Integer>lengths=newArrayList<>();byte[]encodedSonnetsBytesArray=null;// 第一步:压缩所有 Sonnet 并拼接到内存流try(ByteArrayOutputStreamencodedSonnets=newByteArrayOutputStream()){for(Sonnetsonnet:sonnets){byte[]sonnetCompressedBytes=sonnet.getCompressedBytes();offsets.add(encodedSonnets.size());// 当前拼接流的大小就是下一个 Sonnet 的 offsetlengths.add(sonnetCompressedBytes.length);encodedSonnets.write(sonnetCompressedBytes);}// 第二步:写入文件头dos.writeInt(numberOfSonnets);for(intindex=0;index<numberOfSonnets;index++){dos.writeInt(offsets.get(index));dos.writeInt(lengths.get(index));}encodedSonnetsBytesArray=encodedSonnets.toByteArray();}// 第三步:写入所有压缩内容sonnetFile.write(encodedSonnetsBytesArray);}catch(IOExceptione){e.printStackTrace();}

🔍 代码解析

  1. offsets.add(encodedSonnets.size())
    • encodedSonnets.size()返回当前拼接流的长度,也就是下一首 Sonnet 在字节数组中的起始位置。
  2. lengths.add(sonnetCompressedBytes.length)
    • 存储当前 Sonnet 的压缩字节数。
  3. dos.writeInt(numberOfSonnets)
    • 写入总数(方便后续读取时知道有多少首)。
  4. dos.writeInt(offsets.get(index)); dos.writeInt(lengths.get(index));
    • 按顺序写入 offset 和 length,形成一个“索引表”。
  5. sonnetFile.write(encodedSonnetsBytesArray)
    • 最后把所有拼接好的字节流一次性写入文件。

📌 使用示例

运行代码后,会在files/sonnets.bin生成一个二进制文件。它的结构大概是这样的:

[Header]154(总数)0120(1首起始=0,长度=120字节)120130(2首起始=120,长度=130字节)...[Body][GZIP压缩后的Sonnet字节内容...]

🚀 总结

  1. 单个 Sonnet 压缩 →getCompressedBytes()
  2. 所有 Sonnet 拼接 →ByteArrayOutputStream
  3. 索引表写入 →DataOutputStream
  4. 最终文件结构 =Header + Body

这样,我们就能高效存储所有 154 首 Sonnet,既节省空间,又能快速定位到任意一首诗。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 8:19:23

openEuler安装redis

openeuler版本 :24.03 方法一&#xff1a;yum快速安装 openEuler 官方源已内置 Redis&#xff0c;一条命令即可完成&#xff0c;适合快速搭建测试环境 yum安装的redis版本可能会较老 # 1. 安装 Redis sudo yum install -y redis# 2. 验证安装 redis-cli --version# 3. 启动 Red…

作者头像 李华
网站建设 2026/5/23 8:19:02

从LIKE暴力匹配到LLM智能分类——遗留系统数据分析实战

从LIKE暴力匹配到LLM智能分类——遗留系统数据分析实战 文章目录从LIKE暴力匹配到LLM智能分类——遗留系统数据分析实战一、故事的起点二、LIKE暴力分类&#xff1a;笨但能跑三、包厢利用率&#xff1a;把时间轴展开四、如果现在重做&#xff1a;用LLM做分类4.1 不需要7B&#…

作者头像 李华
网站建设 2026/5/23 8:11:31

AI写论文的高效秘籍!4款AI论文写作工具,让写论文变得更简单!

AI论文写作工具推荐 是不是还在为写期刊论文而烦恼不已&#xff1f;面对无尽的文献资料、繁琐的格式要求和不断的修改&#xff0c;许多学术人员都感到写作效率低下。别担心&#xff0c;今天我为大家带来了四款经过实测的AI论文写作工具&#xff0c;它们将从论文文献检索、论文…

作者头像 李华
网站建设 2026/5/23 8:05:44

Keil C51函数指针调用中的递归警告解析与优化

1. 问题现象解析在Keil C51开发环境中&#xff0c;当使用函数指针调用包含字符串常量的函数时&#xff0c;BL51链接器会抛出"Warning L13: Recursive Call to Segment"警告。这个看似晦涩的警告实际上揭示了嵌入式C编程中一个重要的内存管理机制。让我们通过一个典型…

作者头像 李华