当前位置: 首页 > news >正文

文本文件与基于二进制文件的存储的学生管理系统

文本文件与基于二进制文件的存储的学生管理系统


目录
  • 文本文件与基于二进制文件的存储的学生管理系统
    • 一、项目介绍
    • 二、包结构
    • 三、核心代码介绍
      • 3.1 代码展示
      • 3.2 代码分析
      • 3.3 对比分析
    • 四、结果展示
    • 五、过程回顾
      • 5.1 问题一:二进制文件的“空”并非空白
      • 5.2 问题二:二进制文件的追加陷阱

一、项目介绍

本项目旨在对学生管理系统进行优化,重点在于实现数据持久化。我们通过支持文本与二进制两种存储格式,为系统提供了灵活且可靠的长

期数据保存方案。


二、包结构

StudentsManagementSystemProject/
├── src/
│ └── code/
│ ├── Main.java // 程序入口,UI与主业务逻辑
│ ├── Student.java // 学生数据模型
│ ├── StudentManagementSystemInterface.java // 数据操作接口定义
│ ├── File.java // 文件操作工具类
│ ├── StudentManagementSystem1.java // 基于二进制文件的数据管理实现
│ └── StudentManagementSystem.java // 基于文本文件的数据管理实现
├── data.txt // 文本格式数据文件
└── data1.txt // 二进制格式数据文件

三、核心代码介绍

3.1 代码展示

File.java
该类采用了静态工具类模式,将所有文件读写操作封装起来,实现了业务逻辑与文件操作的解耦

点击查看代码
package code;import java.io.*;
import java.util.ArrayList;
import java.util.List;public class File {public static void appendStudentToTextFile(String filename,String data) {try(FileOutputStream fos = new FileOutputStream(filename,true);OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");BufferedWriter bw = new BufferedWriter(osw)) {bw.write(data);} catch (IOException e) {System.err.println("追加学生到文本文件失败: " + filename);e.printStackTrace();}}public static void writeAllStudentsToTextFile(String filename,List<Student> students) {try(FileOutputStream fos = new FileOutputStream(filename);OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");BufferedWriter bw = new BufferedWriter(osw)) {for(Student s : students) {bw.write(s.StringBuild());}} catch (IOException e) {System.err.println("写入所有学生到文本文件失败: " + filename);e.printStackTrace();}}public static List<Student> readAllStudentsFromTextFile(String filename) {List<Student> students = new ArrayList<>();try (FileInputStream fis = new FileInputStream(filename);InputStreamReader isr = new InputStreamReader(fis, "UTF-8");BufferedReader br = new BufferedReader(isr)) {String line;while ((line = br.readLine()) != null) {String[] parts = line.split(",");if (parts.length == 6) {Student s = new Student(parts[0], Integer.parseInt(parts[1]), parts[2], parts[3], parts[4], Double.parseDouble(parts[5]));students.add(s);}}} catch (IOException e) {System.err.println("从文本文件读取学生失败: " + filename);e.printStackTrace();}return students;}public static void writeAllStudentsToBinaryFile(String filename,List<Student> students) {try (FileOutputStream fos = new FileOutputStream(filename);BufferedOutputStream bos = new BufferedOutputStream(fos);ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(students);} catch (IOException e) {System.err.println("写入所有学生到二进制文件失败: " + filename);e.printStackTrace();}}public static List<Student> readAllStudentsFromBinaryFile(String filename){List<Student> students= new ArrayList<>();try (FileInputStream fis = new FileInputStream(filename);BufferedInputStream bis = new BufferedInputStream(fis);ObjectInputStream ois = new ObjectInputStream(bis)) {students = (List<Student>) ois.readObject();} catch (EOFException e) {//空白}catch (IOException | ClassNotFoundException e) {System.err.println("从二进制文件读取学生失败: " + filename);e.printStackTrace();}return students;}
}

3.2 代码分析

  1. 静态工具类模式

  2. 装饰器模式在IO流中的应用

  • FileOutputStream: 打开一个到文件的连接,并以字节的形式向文件中写入原始数据

  • OutputStreamWriter: 是一个字符到字节的桥梁,它装饰了 FileOutputStream,使其具备了处理字符的能力

  • BufferedWriter: 修饰了 OutputStreamWriter ,为其增加了缓冲区

  1. Java序列化机制
  • ObjectOutputStream: 将Java对象序列化,并写入到二进制文件中

  • ObjectInputStream: 反序列化的核心,将之前通过 ObjectOutputStream 序列化的字节流还原成原始的Java对象

3.3 对比分析

对比 文本文件 二进制文件
读取方式 人类可读,需要用文本编辑器或按字符编码读取 机器可读,人眼看过去是乱码,必须用专门的程序按二进制格式解析
文件形态 由字符编码(如ASCII, UTF-8)构成,内容是字符序列 由比特流构成,内容是字节序列,形态完全由程序定义
存储效率 较低 ,数字等类型需转为字符串,占用更多空间 非常高,数据按内存格式存储,紧凑无冗余
追加操作 天然支持,每行独立,追加不影响旧数据。 严格禁止。会破坏文件结构,导致读取失败

四、结果展示

  • 文本文件存储 (data.txt)
    数据以CSV格式存储,结构清晰,易于人工查看和编辑。

image

  • 二进制文件存储 (data1.txt)
    数据以二进制形式存储,内容无法直接阅读,但保证了数据的高效与安全。

image

五、过程回顾

5.1 问题一:二进制文件的“空”并非空白

现象:删除所有数据后,二进制文件大小不为零

分析与反思:

二进制序列化文件并非在无数据时变为空白。ObjectOutputStream 在创建或覆盖文件时,会首先写入一个魔数和版本标识符作为文件头。

这个文件头是反序列化时识别文件格式的依据,因此一个“空”的二进制文件实际上包含了元数据,而非零字节。

image

5.2 问题二:二进制文件的追加陷阱

现象:模仿文本文件追加数据后,读取时抛出 StreamCorruptedException

分析与反思:

在实现二进制文件存储时,一个常见的误区是模仿文本文件的追加模式。然而,这种做法对于Java序列化文件是致命的。

ObjectOutputStream 在初始化时会向文件写入一个序列化协议头(包含魔数和版本号)。当使用追加模式时,每次写入都会在文件末尾重

复添加这个协议头,从而在数据流中制造了非法的“断点”。这导致 ObjectInputStream 在反序列化时因无法解析预期的对象数据而抛出

StreamCorruptedException,使得整个文件数据无法被正确读取。

解决方案:采用“读-改-写”模式。每次更新数据时,都需将文件全部内容读入内存,修改后,再完整地覆盖写回文件。这确保了文件始终只有一个合法的文件头。

a4c7591710fa71c6e8c3c352e05de4ad

http://www.jsqmd.com/news/49835/

相关文章:

  • Linux 中grep命令在文本中匹配单个的字母
  • Docker Compose 安装问题排查全记录(WSL2 Ubuntu 22.04 环境)
  • 一些 DS
  • newDay22
  • B4324 双向链表
  • 系列最便宜!苹果iPhone 17e要来了:60Hz低刷灵动岛屏幕
  • Codeforces Round 1065 (Div. 3)
  • 代码随想录算法训练营第四天:链表part02
  • CF2027A-Rectangle Arrangement
  • 线段树全家桶
  • 用 Node.js 实现英文数字验证码识别
  • 用 Rust 和 Tesseract OCR 实现英文数字验证码识别
  • 在Java中调用第三方接口并返回第三方页面
  • 251124省运会结束啦
  • 用 C# 和 Tesseract 实现英文数字验证码识别
  • 有了TCP为什么还需要HTTP?再用RPC?这次彻底讲明白了
  • 11.24午夜盘思
  • Java调用第三方接口的方法
  • 2025留学代写危机应对指南:5家靠谱机构助你重返校园
  • 2025美国大学停学应对全攻略:5大靠谱机构助你重返学术轨道
  • 2025美国紧急转学机构推荐深度解析:靠谱机构认准这些核心优势,危机中重启留学之路​
  • 第35天(中等题 数据结构)
  • 2025美国留学求职机构实力解析:你的职场Offer引路人在哪?
  • Universal Fit 3-Button Metal Flip Remote Key (5pcs/lot) – KEYDIY KD NB29-3 for Euro/American Cars
  • 2025美国科研中介TOP5解析:从课题对接至成果落地全程护航
  • 根据缺少的文件查找deb包
  • 第一个Vue2程序
  • 2025美国留学生求职中介TOP5:厚仁教育领衔,精准匹配名企资源
  • CF1097F Alex and a TV Show
  • Git 最速上手