这个作业属于哪个课程 | 2302软件工程 |
---|---|
这个作业要求在哪里 | 软件工程实践第二次作业—文件读取 |
这个作业的目标 | 完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序 |
其他参考文献 | 《源代码管理》,fastjson教程 |
文章目录
Gitcode项目地址
psp表格
PSP阶段 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
• Estimate | - 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 600 | 650 |
• Analysis | - 需求分析(包括学习新技术) | 120 | 100 |
• Design Spec | - 生成设计文档 | 40 | 50 |
• Design Review | - 设计复审 | 60 | 60 |
• Coding Standard | - 代码规范 (为目前的开发制定合适的规范) | 20 | 30 |
• Design | - 具体设计 | 120 | 60 |
• Coding | - 具体编码 | 500 | 400 |
• Code Review | - 代码复审 | 120 | 90 |
• Test | - 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | 210 | 120 |
• Test Report | - 测试报告 | 80 | 60 |
• Size Measurement | - 计算工作量 | 60 | 60 |
• Postmortem & Process Improvement Plan | - 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 2130 | 1880 |
描述解题思路
如何从datas文件夹提取json文件
1.首先从event.json文件进行入手:
从 JSON 对象中获取名为 “Sports” 的 JSON 数组,其中每个元素代表一个体育项目。遍历 “Sports” 数组,对于每个体育项目,获取名为 “DisciplineList” 的 JSON 数组,其中包含该项目的所有项目。然后再遍历 “DisciplineList” 数组,对于每个项目,提取 “Id” 和 “DisciplineName” 字段的值,如图
2.然后是athletes.json
遍历 JSON 数组中的每个元素,对于每个元素,获取一个 JSON 对象。从 JSON 对象中提取名为 “CountryName” 的字段值,表示参赛国家的名称。从 JSON 对象中提取名为 “Participations” 的字段值,这是一个 JSON 数组,包含该国家的参赛选手信息。遍历 “Participations” 数组,对于每个参赛选手,提取他们的姓、名和性别信息。如图
最后是result文件夹下面
从 JSON 对象中获取名为 “Heats” 的 JSON 数组,其中每个元素代表一个热身赛。遍历 “Heats” 数组,对于每个热身赛,获取热身赛的名称属性 “Name”。从该热身赛对象中提取名为 “Results” 的 JSON 数组,其中包含该热身赛的结果信息。遍历 “Results” 数组,对于每个结果,提取总分数 “TotalPoints”、姓名 “FullName” 和排名 “Rank”。从结果对象中提取名为 “Dives” 的 JSON 数组,其中包含该结果的每次跳水得分。遍历 “Dives” 数组,对于每次跳水,提取跳水得分 “DivePoints”,并将其添加到 PartScore 列表中。如图
逻辑判断思路
通过DWASearch类的main函数进行运行,通过命令行参数进行对input.txt的指令进行传入,再根据指令来进行输出,并且输出到output.txt文件上
接口设计和实现过程
接口设计
提供了一个内部类 FileHandler,用于处理文件读写操作和执行命令。
并且提供了一个内部类 JsonHandler,用于处理 JSON 数据的解析和处理。
其中,FileHandler类下面的
- Write_Command_Players函数实现了players指令处理,
- Write_Command_Result函数实现了result指令处理
- WriteError(): 将错误信息写入输出文件。
- WriteNA(): 将 “N/A” 信息写入输出文件。
其中,JsonHandler类下面的
- ProcessDetails(String jsonStr) 解析detail指令对应json文件
- ProcessResult(String jsonStr) 解析result指令对应json文件
- ProcessPlayer(String jsonStr) 解析player指令对应json文件
- ProcessEvent(String jsonString) 解析event.json文件
在编写json解析过程还运用到了fastjson库,使用到了其提供的getJSONObject(),**getJSONArray()**等等方法
实现过程
从DWASearch函数的main方法入口,读取input.txt使用filehandler,根据对应的指令进行不同的write函数操作,
filehandler再使用JsonHandler对不同类型的json进行解析,最后输出到output.txt文件夹
关键代码
- Write_Command_Players和Write_Command_Result函数的实现
public void Write_Command_Players() throws IOException {
String fileName = "datas/athletes.json"; // 文件目录
String jsonArrayString = DoReadFile(fileName);
jsonHandler.ProcessPlayers(jsonArrayString);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(output, true))) {
for (Player player : JsonHandler.playerArrayList) {
System.out.println(player);
writer.write(player.toString());//写到output文件
}
}
}
public void Write_Command_Result(String event) throws IOException {
String fileName = "datas/event.json"; // 文件目录
String jsonString = DoReadFile(fileName);
if (JsonHandler.Event_NametoId.isEmpty())//如果map是空的就先运行保存一下
jsonHandler.ProcessEvent(jsonString);
if (JsonHandler.Event_NametoId.containsKey(event)) {
System.out.println("找到了!");
String ResultFileName = "datas/results/" + JsonHandler.Event_NametoId.get(event) + ".json";
String jsonStr = DoReadFile(ResultFileName);
jsonHandler.ProcessResult(jsonStr);//处理result指令
try (BufferedWriter writer = new BufferedWriter(new FileWriter(output, true))) {
for (ResultPlayer resultPlayer : JsonHandler.playerResultArrayList) {
System.out.println(resultPlayer);
writer.write(resultPlayer.toString());
}
}
JsonHandler.playerResultArrayList.clear();//打印完清空,防止影响到下个操作
} else {//没有找到退出函数
System.out.println("没有找到该项目!");
WriteNA();
}
}
- ProcessPlayer(String jsonStr) 的实现
public void ProcessPlayers(String jsonArrayString) {
JSONArray jsonArray = JSONArray.parseArray(jsonArrayString);//将读取的json字符串转变为json数组
// 遍历 JSONArray,处理每个 JSON 对象
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
// 获取 CountryName 和 Participations 的值
String countryName = jsonObject.getString("CountryName");
JSONArray participationsArray = jsonObject.getJSONArray("Participations");
// 遍历 Participations 数组,获取每个运动员的姓名
for (int j = 0; j < participationsArray.size(); j++) {
JSONObject participation = participationsArray.getJSONObject(j);
String Gender;
String lastName = participation.getString("PreferredLastName");
String firstName = participation.getString("PreferredFirstName");
int flag = participation.getIntValue("Gender");
if (flag == 1) {//说明是女性
Gender = "Female";
} else Gender = "Male";//否则男性
playerArrayList.add(new Player(Gender, countryName, firstName, lastName));//最后添加到playerArrayList里面
}
}
程序性能改进
- 对event.json解析的时候开始将项目名字和对应的id通过数组储存,发现速度太慢,后面改用成hashmap进行存储,提升了程序速度
- 没有使用文件流,而是改使用BufferdWriter包装FileWriter去对输出流进行控制,提升了速度.
改进后代码
private String DoReadFile(String fileName) {//这个函数用来读取json文件并且返回json字符串
String line;
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {//打开athletes.json
while ((line = br.readLine()) != null) {
contentBuilder.append(line);
}
} catch (IOException e) {
System.out.println("读取文件时出错:" + e.getMessage());
}
return contentBuilder.toString();
}
进行测试
测试了DWAsearch类的测试结果如下
异常处理
参数异常处理
try {
if (args.length != 2) {
System.out.println("输入的参数个数错误!");
throw new IOException();
}
文件异常处理
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {//打开athletes.json
while ((line = br.readLine()) != null) {
contentBuilder.append(line);
}
} catch (IOException e) {
System.out.println("读取文件时出错:" + e.getMessage());
}
心路历程
9.心路历程与收获
在文件处理的路径,上相对路径绝对路径搞不清楚,花了很多时间,还有对json文件格式不熟悉,对maven不熟悉,配置导入都搞不清楚.浪费大量时间,学习编程任重道远.