103
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于哪个课程 | 软件工程实践2022年春-F班 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践第二次作业 |
| 这个作业的目标 | 使用命令行 从网络上获取冬奥会奖牌榜和赛程的数据 并输出 |
| 其他参考文献 | CSDN、博客园 |
m0_46536118 / PersonalProject-Java
| PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | ||
| • Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
| Development | 开发 | ||
| • Analysis | • 需求分析 (包括学习新技术) | 60 | 80 |
| • Design Spec | • 生成设计文档 | 30 | 50 |
| • Design Review | • 设计复审 | 20 | 30 |
| • Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
| • Design | • 具体设计 | 30 | 40 |
| • Coding | • 具体编码 | 300 | 400 |
| • Code Review | • 代码复审 | 30 | 120 |
| • Test | • 测试(自我测试,修改代码,提交修改) | 300 | 500 |
| Reporting | 报告 | ||
| • Test Repor | • 测试报告 | 90 | 120 |
| • Size Measurement | • 计算工作量 | 30 | 30 |
| • Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 60 |
| 合计 | 960 | 1480 |

根据提供的冬奥会网站,审查元素找到对应的奖牌和赛程json文件
冬奥专栏
之后使用java自带的HTTP(java.net.HTTPURLConnection)构造并发送GET请求获取json字符串。
使用HTTP获取数据,处理字符串,创建对应类后使用gson解析库来解析
项目的类分为三种 工具类 实体类 业务类。
工具类有文件类用于输入输出文件、HTTP类用于获取需要的冬奥会数据。
实体类有奖牌类和赛程类,用于json解析。
业务类有getData和outPutData用于控制业务逻辑。
最终的项目结构如图

OlympicSearch.java
public class OlympicSearch {
public static void main(String[] args) {
if(args.length!=2) {
System.out.println("运行格式异常,正确格式需要加上输入文件和输出文件");
return;
}
ArrayList<String> requestType =new ArrayList<>();
//按行读取input文件内容
try {
FileInputStream inputStream = new FileInputStream(args[0]);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str;
while((str = bufferedReader.readLine()) != null){
requestType.add(str);
}
//close
inputStream.close();
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("未找到该文件");
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
OutputData out=new OutputData(requestType);
out.outPutToFile(args[1]);
}
}
getSchedule
public void getSchedule(String date)
{
int dateInt=Integer.parseInt(date);
Gson gson = new Gson();
String jsonString = file.readFile("data/schedule/"+date+".json");
try{
scheduleFile sf = gson.fromJson(jsonString, scheduleFile.class);
fileString[dateInt-201]=sf.data.getSchedule();
}catch (Exception e){
//解析文件夹中的json文件失败后需要重新爬取json文件
if(!getData.getFile(date)){
System.out.println("json文件损坏,并且爬取数据失败");
}
else {
System.out.println("json文件损坏,已经重新爬取文件");
jsonString = file.readFile("data/schedule/"+date+".json");
scheduleFile sf = gson.fromJson(jsonString, scheduleFile.class);
fileString[dateInt-201]=sf.data.getSchedule();
}
}
}
getTotal
public void getOutput()
{
Gson gson = new Gson();
String jsonString = file.readFile("data/total.json");
try{
totalFile tf = gson.fromJson(jsonString, totalFile.class);
fileString[0]=tf.data.getListByRank();
}catch (Exception e){
//解析文件夹中的json文件失败后需要重新爬取json文件
if(!getData.getFile("total")){
System.out.println("json文件损坏,并且爬取数据失败");
}
else {
System.out.println("json文件损坏,已经重新爬取文件");
jsonString = file.readFile("data/total.json");
totalFile tf = gson.fromJson(jsonString, totalFile.class);
fileString[0]=tf.data.getListByRank();
}
}
}
第一个版本的流程为每读入一行 根据该行的数据解析json字符串后输出到对应文件。
第一次改进: 每读入一行解析一次json字符串花销太大 所以让程序保存需要输出的数据
下次需要输出相同的数据可以使用已保存的而不用再次去解析json。
第二次改进:每读入一行输出一次到文件中反复打开文件的开销太大 所以让程序使用一个ArrayList保存需要输出的代码标号 最后根据ArrayList拼接所有需要输出的字符串后输出。
最终两万行输入耗时平均耗时900ms
内存平均占用237mb

data文件夹存在对应文件不需要HTTP获取


in.txt为输入文件 out.txt为输出文件 expected.txt为预期文件
测试代码使用输入文件输出到输出文件 之后读取输出文件和预期文件的内容进行对比
@Test
public void outPutToFile(){
ArrayList<String> requestType =new ArrayList<>();
//按行读取input文件内容
try {
FileInputStream inputStream = new FileInputStream("in.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str;
while((str = bufferedReader.readLine()) != null){
requestType.add(str);
}
//close
inputStream.close();
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("未找到该文件");
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
OutputData out=new OutputData(requestType);
out.outPutToFile("out.txt");
String outFile=readFile("out.txt");
String expected=readFile("expected.txt");
Assert.assertEquals(expected,outFile);
}
@Test
public void getOutput() {
ArrayList<String> requestType =new ArrayList<>();
OutputData ou=new OutputData(requestType);
ou.getOutput();
String expected=readFile("1.txt");
Assert.assertEquals(expected,ou.fileString[0]);
}
@Test
public void getSchedule() {
ArrayList<String> requestType =new ArrayList<>();
OutputData ou=new OutputData(requestType);
ou.getSchedule("0215");
String expected=readFile("1.txt");
Assert.assertEquals(expected,ou.fileString[14]);
}
命令行读取时参数个数异常 会提醒输入参数错误 并结束程序
数据文件不存在时会自动使用HTTP获取数据
数据文件损坏或者被修改 会使用HTTP重新获取数据
开始编码前最重要的是先弄清楚需求。
之后要先设计程序的大体结构 再设计接口 使程序的代码可迁移。
最后开始具体的函数编码。
测试是繁琐的,但是十分重要。
解题思路用流程图描述的十分清晰,点赞!异常处理最好能把用例和测试结果也一起写入博客。