本文主要是介绍Java进阶总结案例(小说阅读器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用工具 IntelliJ IDEA Community Edition 2023.1.4
使用语言 Java8
代码能力快速提升小方法,看完代码自己敲一遍,十分有用
目录
1.案例需要实现模块
1.1 项目架构
2.实现代码
2.1 工具类
2.1.1 常量类
2.1.2 用户工具类
2.1.3 小说工具类
2.1.4 其他功能类
2.1.5 日志框架
2.2 用户功能
2.2.1 创建用户类
2.2.2 创建用户功能类
2.2.3 创建注册功能类
2.2.4 创建登录功能类
2.2.5 创建用户选择功能类
2.3 小说功能
2.3.1 创建小说类
2.3.2 创建小说类别类
2.3.3 创建小说功能类
2.3.4 创建言情小说功能类
2.3.5 创建武侠小说功能类
2.3.6 创建选择小说功能类
2.4 运行类
2.4.1 运行类代码
1.案例需要实现模块
功能模块:登录,注册,小说类型列表,小说列表,上传小说,阅读小说,这是一个阅读器小工具。
1.1 项目架构
- config:存放系统运行数据(用户信息、小说类型信息、小说列表信息)
- novels:存放上传的txt小说
- client:存放启动类程序(只放main()方法启动类)
- common:存放公共类
- constants:存放静态常量类
- util:存放工具类(IO流放进去)
- entity:存放存储数据所需的实体类(平时创建的对象类,比如用户类)
- service:存放与功能服务相关的类(接口类、抽象类、实现类)
- lib:存放架包
- dao:接口抽象类都放这个
添加数据到config目录下
- users.dat:存储用户信息
- novels.dat:存储小说集合信息
添加Log4j2日志需要的架包
log4j-api-2.23.0.jar与log4j-core-2.23.0.jar(任意版本皆可)
最终架构结果
2.实现代码
2.1 工具类
2.1.1 常量类
package cn.ksb.minitxt.common.constants;/*** 阅读器中的常量属性*/
public class ReaderCon {/*** 阅读器的头*/public static final String HEAD = "欢迎使用书虫阅读器";/*** 阅读器的分割线*/public static final String SEPARATE = "--------------------";/*** 登录选项*/public static final String LOGIN = "1.登录";/*** 注册选项*/public static final String REGISTER = "2.注册";/*** 退出选项*/public static final String EXIT = "3.退出";/*** 选择功能*/public static final String SELECT = "请选择:";/*** 谢谢使用*/public static final String EXITRESULT = "谢谢使用!";/*** 输入异常*/public static final String INPUTEX = "您的输入有误!";/*** 其他异常*/public static final String EX = "未知异常!";/*** IO流异常*/public static final String IOEX = "发生流异常,请重试!";/*** 用户序列化路径属性*/public static final String URL = "./config/users.dat";/*** 书本序列化路径属性*/public static final String NOVELURL="./config/novels.dat";/*** 言情选择*/public static final String ROMANTICNOVEL="1.言情";/*** 武侠选择*/public static final String WUXIANOVEL="2.武侠";/*** 言情小说的头*/public static final String RomHEAD="------------言情小说列表开始------------";/*** 武侠言情小说的底*/public static final String NOVELBOTTOM="--------------小说列表结束--------------";/*** 武侠小说的头*/public static final String WUXIAHEAD="------------武侠小说列表开始------------";/*** 武侠名*/public static final String WUXIANAME="武侠";/*** 言情名*/public static final String ROMNAME="言情";}
2.1.2 用户工具类
package cn.ksb.minitxt.common.util;import cn.ksb.minitxt.common.constants.ReaderCon;import java.io.*;/*** 用户文件工具类*/
public class UserFileUtil {/*** 用户序列化方法** @param obj 用户序列化的内容* @throws IOException 用户序列化可能发生的异常*/public void writerObject(Object obj) throws IOException {FileOutputStream fileOutputStream = new FileOutputStream(ReaderCon.URL);//使用文件输出流获取路径ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);//使用对象输出流序列化out.writeObject(obj);//输出数据out.flush();//把缓冲区的数据也刷出去,不然登录时无法找到}/*** 用户反序列化方法** @return 反序列化的对象* @throws IOException 用户反序列化可能发生的异常*/public Object readerObject() throws IOException {FileInputStream fileInputStream = new FileInputStream(ReaderCon.URL);//使用文件输入流获取路径return new ObjectInputStream(fileInputStream);//返回对象输入流对象}
}
2.1.3 小说工具类
package cn.ksb.minitxt.common.util;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.dao.NovelDao;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.service.WuXiaService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.io.*;
import java.util.ArrayList;/*** 书本文件工具类*/
public class NovelFileUtil {/*** 日志属性*/protected static Logger logger = LogManager.getLogger(NovelDao.class);/*** 书本序列化方法** @param obj 用户序列化的内容* @throws IOException 用户序列化可能发生的异常*/public static void writerObject(Object obj) throws IOException {FileOutputStream fileOutputStream = new FileOutputStream(ReaderCon.NOVELURL);//使用文件输出流获取路径ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);//使用对象输出流序列化out.writeObject(obj);//输出数据out.flush();//把缓冲区的数据也刷出去,不然查找时无法找到}/*** 书本反序列化方法** @return 反序列化的对象* @throws IOException 用户反序列化可能发生的异常*/public static Object readerObject() throws IOException {FileInputStream fileInputStream = new FileInputStream(ReaderCon.NOVELURL);//使用文件输入流获取路径return new ObjectInputStream(fileInputStream);//返回对象输入流对象}/*** 获取书籍内容方法** @param src 书籍路径* @return 返回字符输入流对象*/public static Object reader(String src) {BufferedReader input = null;try {Reader reader1 = new FileReader(src);//创建字符输入流对象input = new BufferedReader(reader1);//新建buffered输入流对象} catch (FileNotFoundException e) {System.out.println(ReaderCon.IOEX);logger.error(NovelFileUtil.class.getName() + "类发生了" + e.getMessage() + "异常!");}return input;}
}
2.1.4 其他功能类
package cn.ksb.minitxt.dao;import cn.ksb.minitxt.client.Run;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.util.Scanner;/*** 其他功能类*/
public abstract class BaseDao {/*** 输入属性*/public Scanner input = new Scanner(System.in);/*** 展示功能方法*/protected abstract void printFunction();
}
2.1.5 日志框架
<?xml version="1.0" encoding="UTF-8" ?>
<configuration status="OFF"><appenders><!--输出日志到控制台的配置--><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%m%n%l"/></Console><!--输出日志到文件的配置--><File name="log" fileName="logs/oop.log"><PatternLayout pattern="%d [%t] %-5p [%c]-%m%n"/></File></appenders><loggers><root level="ALL"><appender-ref ref="Console"/><appender-ref ref="log"/></root></loggers>
</configuration>
2.2 用户功能
2.2.1 创建用户类
package cn.ksb.minitxt.entity;import java.io.Serializable;
import java.util.HashMap;/*** 用户类*/
public class User implements Serializable {private static final long serialVersionUID = 3L;/*** 用户账号密码集合属性*/public HashMap<String, String> map = new HashMap<>();}
2.2.2 创建用户功能类
package cn.ksb.minitxt.dao;import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.util.ArrayList;
import java.util.Scanner;/*** 用户功能类*/
public abstract class UserDao {/*** 输入属性*/public Scanner input = new Scanner(System.in);/*** 日志属性*/protected static Logger logger = LogManager.getLogger(UserDao.class);/*** 添加用户和登录用户息方法** @param user 用户对象,让登录和注册共用一个对象* @param list 书本对象*/protected abstract void loginAndReg(User user, ArrayList<Novel> list) ;
}
2.2.3 创建注册功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.UserFileUtil;
import cn.ksb.minitxt.dao.UserDao;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.User;import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;/*** 注册功能类*/
public class RegService extends UserDao {/*** 用户注册登录名*/private String name;/*** 用户注册密码*/private String pwd1;/*** 用户注册输入第二次密码*/private String pwd2;/*** 判断输入是否成功*/private boolean flag;@Overridepublic void loginAndReg(User user, ArrayList<Novel> list) {try {System.out.println("请输入登录名:");//输入注册登录名this.name = input.next();System.out.println("请输入密码:");//输入注册密码1this.pwd1 = input.next();System.out.println("请再次输入密码:");//输入注册密码2this.pwd2 = input.next();IfReg(user,list);} catch (IOException | ClassNotFoundException e) {System.out.println(ReaderCon.IOEX);logger.error(RegService.class.getName()+"类发生了" + e.getMessage() + "异常!");//记录发生异常信息}}/*** 判断注册结果方法** @param user 用户对象* @throws IOException 可能发生的异常* @throws ClassNotFoundException 可能发生的异常*/public void IfReg(User user, ArrayList<Novel> list) throws IOException, ClassNotFoundException {UserFileUtil util = new UserFileUtil();//新建用户工具类(包含IO流)if (!this.pwd2.equals(this.pwd1)) {//判断两次密码是否输入一致,一致就继续往下走,不一致就执行该代码块内容System.out.println("注册失败,两次输入的密码不一致!");//控制台打印注册失败flag = false;//注册条件1} else {flag = true;}boolean flag1 = true;//创建注册条件2,用于判断是否有重复的登录名Set<String> set = user.map.keySet();//取到用户对象中存取键(登录名)和值(密码)的所有键for (String key : set) {//遍历键if (key.equals(name)) {//判断是否有相同的键(登录名)System.out.println("用户名已存在,请重新注册!");flag1 = false;//相同就把注册条件2设为false}}if (flag && flag1) {//如果两个条件都成立就走以下代码块System.out.println("用户注册成功,请登录!");user.map.put(name, pwd1);//把注册的信息存入集合中util.writerObject(user.map);//把用户集合序列化,覆盖上次内容LoginService loginFunction = new LoginService();//然后进行登录操作loginFunction.loginAndReg(user,list);//调用登录方法}}public String getName() {return name;}public String getPwd1() {return pwd1;}public String getPwd2() {return pwd2;}public boolean isFlag() {return flag;}
}
2.2.4 创建登录功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.UserFileUtil;
import cn.ksb.minitxt.dao.UserDao;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.User;import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Set;public class LoginService extends UserDao {/*** 判断是否登录成功*/private boolean flag = false;@Overridepublic void loginAndReg(User user, ArrayList<Novel> list) {try {System.out.println("请输入登录名:");//输入登录名String name = input.next();System.out.println("请输入密码:");//输入密码String pwd = input.next();IfLogin(name, pwd, user, list);//把登录名和密码还有用户对象传进去} catch (IOException | ClassNotFoundException e) {System.out.println(ReaderCon.IOEX);logger.error(LoginService.class.getName() + "类发生了" + e.getMessage() + "异常!");//记录发生异常信息}}/*** 判断是否登录成功方法** @param name 登录名* @param pwd 登录密码* @param user 用户对象* @throws IOException 可能发生的异常* @throws ClassNotFoundException 可能发生的异常*/public void IfLogin(String name, String pwd, User user, ArrayList<Novel> list) throws IOException, ClassNotFoundException {UserFileUtil util = new UserFileUtil();//创建用户工具对象(包含IO流)RomService romService = new RomService();//创建言情书本对象WuXiaService wuXiaService=new WuXiaService();//创建武侠书本对象if (!user.map.isEmpty()) {//判断用户账号信息是否为空,不为空就执行以下代码块,为空就执行else代码块ObjectInputStream objectInputStream = (ObjectInputStream) util.readerObject();//创建对象输入流对象user.map = (HashMap<String, String>) objectInputStream.readObject();//取到对象输入流的内容Set<String> set = user.map.keySet();//取到所有的键for (String key : set) {//遍历键if (name.equals(key) && pwd.equals(user.map.get(key))) {//判断是否有跟当前登录名和密码对应的键(登录名)和值(密码)flag = true;//有的话就把登录条件判断为true(真)}}if (flag) {//登录成功执行代码System.out.println("登录成功!");boolean NovelFlag = true;//循环当前账号书本条件NovelSelectService novelSelectService = new NovelSelectService();//书本信息选择对象while (NovelFlag) {//选择书本,1言情,2.武侠try {novelSelectService.printFunction();//打印可选择的内容switch (novelSelectService.Select()) {//选择case 1:romService.print(list);//打印言情书本功能方法break;case 2:wuXiaService.print(list);//打印武侠书本功能方法break;case 0:NovelFlag = false;//0是退出当前登录break;default:System.out.println("你的输入有误,请重新输入!");}} catch (InputMismatchException e) {System.out.println(ReaderCon.INPUTEX);logger.error(novelSelectService.getClass().getName() + "类发生了" + e.getMessage() + "异常!");//记录异常发生信息}}} else {//登录失败执行代码System.out.println("用户名或密码错误,请重新输入!");}} else {System.out.println("您还没有注册账号,请注册账号!");RegService regFunction = new RegService();//新建注册账号对象regFunction.loginAndReg(user, list);//调用注册方法}}
}
2.2.5 创建用户选择功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.dao.BaseDao;import java.util.InputMismatchException;/*** 选择功能*/
public class SelectService extends BaseDao {/*** 选择选项属性*/int select = -1;@Overridepublic void printFunction() {System.out.println(ReaderCon.HEAD + "\n" + ReaderCon.SEPARATE + "\n" + ReaderCon.LOGIN + "\n" + ReaderCon.REGISTER+ "\n" + ReaderCon.EXIT + "\n" + ReaderCon.SEPARATE + "\n" + ReaderCon.SELECT);//打印可选择内容信息}/*** 输入选择结果方法** @return 输入的选择结果* @throws InputMismatchException 可能会发生的异常*/public int inputSelect() throws InputMismatchException {select = input.nextInt();//把选择结果存入属性return select;//返回选择的选项}
}
2.3 小说功能
2.3.1 创建小说类
package cn.ksb.minitxt.entity;import java.io.Serializable;/*** 小说信息类*/
public class Novel implements Serializable {private static final long serialVersionUID = 1L;/*** 小说名称属性*/private String name;/*** 小说作者属性*/private String author;/*** 小说绝对路径属性*/private String filename;/*** 小说类型对象属性*/private Type type;/*** 小说简介属性*/private String brief;public String getBrief() {return brief;}public void setBrief(String brief) {this.brief = brief;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getFilename() {return filename;}public void setFilename(String filename) {this.filename = filename;}public Type getType() {return type;}public void setType(Type type) {this.type = type;}
}
2.3.2 创建小说类别类
package cn.ksb.minitxt.entity;import java.io.Serializable;/*** 小说类型信息类*/
public class Type implements Serializable {private static final long serialVersionUID = 2L;/*** 小说类型名称属性*/private String name;/*** 该小说类型的存放路径属性*/private String novelPath;public String getName() {return name;}public Type(String name, String novelPath) {this.name = name;this.novelPath = novelPath;}
}
2.3.3 创建小说功能类
package cn.ksb.minitxt.dao;import cn.ksb.minitxt.client.Run;
import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.NovelFileUtil;
import cn.ksb.minitxt.entity.Novel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Scanner;/*** 书本功能类*/
public abstract class NovelDao {/*** 打印书本信息方法*/protected abstract void print(ArrayList<Novel> list);/*** 添加书本方法* @param list 添加书本集合*/protected abstract void add(ArrayList<Novel> list);/*** 输入属性*/public Scanner input = new Scanner(System.in);/*** 日志属性*/protected static Logger logger = LogManager.getLogger(NovelDao.class);/*** 书本内选择功能方法* @return 选择的选项*/protected int select(){System.out.println("0:返回上一级菜单");System.out.println("-1:上传小说");System.out.println("输入小说序号阅读:");return input.nextInt();}/**** 阅读器方法* @param list 书本集合* @param num 选择的小说* @return 返回是否有该书本*/protected abstract boolean Reader(ArrayList<Novel> list,int num);
}
2.3.4 创建言情小说功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.NovelFileUtil;
import cn.ksb.minitxt.dao.NovelDao;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.Type;import java.io.*;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;/*** 言情小说功能类*/
public class RomService extends NovelDao {@Overrideprotected void print(ArrayList<Novel> list) {boolean RomFlag = true;//设置言情小说循环条件while (RomFlag) {//循环言情小说中的选项System.out.println(ReaderCon.RomHEAD);//打印言情小说的头部try {if (!list.isEmpty()) {//如果书本集合不为空就代表有书,即可以进去ObjectInputStream input = (ObjectInputStream) NovelFileUtil.readerObject();//反序列化对象集合ArrayList<Novel> novels = (ArrayList<Novel>) input.readObject();//把反序列化的对象集合赋值出来boolean flag = false;//设置意外情况条件true就代表没有发生,false就代表发生了System.out.println("序号 名称 作者 简介");for (int i = 0; i < novels.size(); i++) {if (list.get(i).getType().getName().equals(ReaderCon.ROMNAME)) {//如果类型是言情小说就打印输出System.out.println((i + 1) + " " + list.get(i).getName() + " " + list.get(i).getAuthor() + " " + list.get(i).getBrief());flag = true;}}if (!flag) {//书本集合中有武侠小说但没有言情小说就走这里System.out.println("已有" + ReaderCon.WUXIANAME + "书籍,但没有" + ReaderCon.ROMNAME + "书籍!");}} else {System.out.println("您当前还没有书籍,请上传书籍!");}} catch (IOException | ClassNotFoundException e) {System.out.println(ReaderCon.IOEX);logger.error(WuXiaService.class.getName() + "类发生了" + e.getMessage() + "异常!");}System.out.println(ReaderCon.NOVELBOTTOM);int num = super.select();switch (num) {//选择言情小说中的操作case -1:this.add(list);//添加小说方法break;case 0:RomFlag = false;//返回上一级break;default:boolean flag = Reader(list, num);//获取书库中是否有该本书的序号if (!flag) {System.out.println("您好,您的书库中没有该本书");//没有该本书}}}}@Overridepublic boolean Reader(ArrayList<Novel> list, int num) {int page = 1;//页数属性ArrayList<String> pageData = new ArrayList<>();//每页的内容String Data = "";//每行的数据try {if (list.size() >= num) {//如果选择的序号小于等于集合长度就代表有该本书int number = 0;//记录每页输出的行数boolean flag = true;//记录是否返回上一级菜单Novel novel = list.get((num - 1));//获取到当前书的信息if (novel.getType().getName().equals(ReaderCon.ROMNAME)) {//判断该本书是否是言情小说BufferedReader bufferedReader = (BufferedReader) NovelFileUtil.reader(novel.getFilename());//获取该本书的字符流对象String data = bufferedReader.readLine();//每次读取一行while (flag) {//循环该本书的内容System.out.println("************************");System.out.println("当前阅读:" + novel.getName());//打印书名while (data != null) {//循环该页内容if (number == 10) {//一页最多10行就停止break;}Data += data+"\n";//记录每行数据data = bufferedReader.readLine();//迭代每行内容number++;}pageData.add(Data);//把每页数据提取到集合中Data = "";//每次提取完之后重新赋为空,方便下次执行System.out.println(pageData.get(page - 1));//一次取一页的数据,根据页数来取System.out.println("当前阅读:" + novel.getName() + "第" + page + "页!");//打印当前阅读的小说和页数System.out.println("0.返回上一级菜单");//选择看完一页的选项System.out.println("1.下一页");if(page>1){//页数必须大于1才能选择上一页System.out.println("2.上一页");}int select = super.input.nextInt();switch (select) {case 1:page++;//页数加1number = 0;//初始化每页行数break;case 2:if(page>1){//以免误输page--;//页数减1number=0;//初始化每页行数}else{System.out.println(ReaderCon.INPUTEX);}break;case 0:flag = false;//退出循环break;default:System.out.println(ReaderCon.INPUTEX);//输入有误}}} else {System.out.println("该本书不是言情小说,无法阅读!");//该本书不是言情小说打印结果}return true;}} catch (IOException e) {System.out.println(ReaderCon.IOEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常!");} catch (InputMismatchException e) {System.out.println(ReaderCon.INPUTEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常!");}return false;//没找到该本书的结果}@Overridepublic void add(ArrayList<Novel> list) {boolean whileFlag = true;//添加循环添加书本条件while (whileFlag) {//循环添加书本Novel novel = new Novel();//创建书本类对象,用于存储添加的小说boolean flag = true;//判断输入的路径是否有误System.out.println("请输入小说名称:");novel.setName(input.next());//输入小说名称System.out.println("请输入作者:");novel.setAuthor(input.next());//输入小说作者System.out.println("请输入简介:");novel.setBrief(input.next());//输入小说简介while (flag) {//如果路径有误就继续循环输入路径System.out.println("请输入上传的txt(请注意路径用/或者\\\\):");novel.setFilename(input.next());//输入路径File file = new File(novel.getFilename());if (file.isFile()) {//判断路径是否是一个文件,是文件就进入,不是文件就继续循环novel.setType(new Type(ReaderCon.ROMNAME, "./novels/romWord/"));try {list.add(novel);//为书本集合添加对象NovelFileUtil.writerObject(list);//把集合覆盖到序列化中} catch (IOException e) {System.out.println(ReaderCon.IOEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常");}flag = false;} else {System.out.println("文件未找到,请确认后重试!");}System.out.println("0:返回上一级菜单");System.out.println("1:继续上传");int num = input.nextInt();//选择是否继续添加书本if (num == 0) {whileFlag = false;}}}}
}
2.3.5 创建武侠小说功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.NovelFileUtil;
import cn.ksb.minitxt.dao.NovelDao;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.Type;import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.InputMismatchException;public class WuXiaService extends NovelDao {@Overrideprotected void print(ArrayList<Novel> list) {boolean RomFlag = true;//设置武侠小说循环条件while (RomFlag) {//循环武侠小说中的选项System.out.println(ReaderCon.WUXIAHEAD);//打印武侠小说的头部try {if (!list.isEmpty()) {//如果书本集合不为空就代表有书,即可以进去ObjectInputStream input = (ObjectInputStream) NovelFileUtil.readerObject();//反序列化对象集合ArrayList<Novel> novels = (ArrayList<Novel>) input.readObject();//把反序列化的对象集合赋值出来boolean flag = false;//设置意外情况条件true就代表没有发生,false就代表发生了System.out.println("序号 名称 作者 简介");for (int i = 0; i < novels.size(); i++) {if (list.get(i).getType().getName().equals(ReaderCon.WUXIANAME)) {//如果类型是言情小说就打印输出System.out.println((i + 1) + " " + list.get(i).getName() + " " + list.get(i).getAuthor() + " " + list.get(i).getBrief());flag = true;}}if (!flag) {//书本集合中有言情小说但没有武侠小说就走这里System.out.println("已有" + ReaderCon.ROMNAME + "书籍,但没有" + ReaderCon.WUXIANAME + "书籍!");}} else {System.out.println("您当前还没有书籍,请上传书籍!");}} catch (IOException | ClassNotFoundException e) {System.out.println(ReaderCon.IOEX);logger.error(WuXiaService.class.getName() + "类发生了" + e.getMessage() + "异常!");}System.out.println(ReaderCon.NOVELBOTTOM);int num = super.select();switch (num) {//选择武侠小说中的操作case -1:this.add(list);//添加小说方法break;case 0:RomFlag = false;//返回上一级break;default:boolean flag = Reader(list, num);//获取书库中是否有该本书的序号if (!flag) {System.out.println("您好,您的书库中没有该本书");//没有该本书}}}}@Overridepublic boolean Reader(ArrayList<Novel> list, int num) {int page = 1;//页数属性ArrayList<String> pageData = new ArrayList<>();//每页的内容String Data = "";//每行的数据try {if (list.size() >= num) {//如果选择的序号小于等于集合长度就代表有该本书int number = 0;//记录每页输出的行数boolean flag = true;//记录是否返回上一级菜单Novel novel = list.get((num - 1));//获取到当前书的信息if (novel.getType().getName().equals(ReaderCon.WUXIANAME)) {//判断该本书是否是武侠小说BufferedReader bufferedReader = (BufferedReader) NovelFileUtil.reader(novel.getFilename());//获取该本书的字符流对象String data = bufferedReader.readLine();//每次读取一行while (flag) {//循环该本书的内容System.out.println("************************");System.out.println("当前阅读:" + novel.getName());//打印书名while (data != null) {//循环该页内容if (number == 10) {//一页最多10行就停止break;}Data += data + "\n";//记录每行数据data = bufferedReader.readLine();//迭代每行内容number++;}pageData.add(Data);//把每页数据提取到集合中Data = "";//每次提取完之后重新赋为空,方便下次执行System.out.println(pageData.get(page - 1));//一次取一页的数据,根据页数来取System.out.println("当前阅读:" + novel.getName() + "第" + page + "页!");//打印当前阅读的小说和页数System.out.println("0.返回上一级菜单");//选择看完一页的选项System.out.println("1.下一页");if (page > 1) {//页数必须大于1才能选择上一页System.out.println("2.上一页");}int select = super.input.nextInt();switch (select) {case 1:page++;//页数加1number = 0;//初始化每页行数break;case 2:if (page > 1) {//以免误输page--;//页数减1number = 0;//初始化每页行数} else {System.out.println(ReaderCon.INPUTEX);}break;case 0:flag = false;//退出循环break;default:System.out.println(ReaderCon.INPUTEX);//输入有误}}} else {System.out.println("该本书不是武侠小说,无法阅读!");//该本书不是武侠小说打印结果}return true;}} catch (IOException e) {System.out.println(ReaderCon.IOEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常!");} catch (InputMismatchException e) {System.out.println(ReaderCon.INPUTEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常!");}return false;//没找到该本书的结果}@Overrideprotected void add(ArrayList<Novel> list) {boolean whileFlag = true;//添加循环添加书本条件while (whileFlag) {//循环添加书本Novel novel = new Novel();//创建书本类对象,用于存储添加的小说boolean flag = true;//判断输入的路径是否有误System.out.println("请输入小说名称:");novel.setName(input.next());//输入小说名称System.out.println("请输入作者:");novel.setAuthor(input.next());//输入小说作者System.out.println("请输入简介:");novel.setBrief(input.next());//输入小说简介while (flag) {//如果路径有误就继续循环输入路径System.out.println("请输入上传的txt(请注意路径用/或者\\):");novel.setFilename(input.next());//输入路径File file = new File(novel.getFilename());if (file.isFile()) {//判断路径是否是一个文件,是文件就进入,不是文件就继续循环novel.setType(new Type(ReaderCon.WUXIANAME, "./novels/wuXiaWord/"));try {list.add(novel);//为书本集合添加对象NovelFileUtil.writerObject(list);//把集合覆盖到序列化中} catch (IOException e) {System.out.println(ReaderCon.IOEX);logger.error(RomService.class.getName() + "类发生了" + e.getMessage() + "异常");}flag = false;} else {System.out.println("文件未找到,请确认后重试!");}}System.out.println("0:返回上一级菜单");System.out.println("1:继续上传");int num = input.nextInt();//选择是否继续添加书本if (num == 0) {whileFlag = false;}}}
}
2.3.6 创建选择小说功能类
package cn.ksb.minitxt.service;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.dao.BaseDao;/*** 选择书本类*/
public class NovelSelectService extends BaseDao {@Overridepublic void printFunction() {System.out.println(ReaderCon.SEPARATE);System.out.println("0.退出登录");System.out.println(ReaderCon.ROMANTICNOVEL);System.out.println(ReaderCon.WUXIANOVEL);System.out.println(ReaderCon.SEPARATE);System.out.println(ReaderCon.SELECT);}/*** 选择选项方法* @return 选择的选项*/public int Select(){return input.nextInt();}
}
2.4 运行类
2.4.1 运行类代码
package cn.ksb.minitxt.client;import cn.ksb.minitxt.common.constants.ReaderCon;
import cn.ksb.minitxt.common.util.NovelFileUtil;
import cn.ksb.minitxt.common.util.UserFileUtil;
import cn.ksb.minitxt.entity.Novel;
import cn.ksb.minitxt.entity.User;
import cn.ksb.minitxt.service.LoginService;
import cn.ksb.minitxt.service.RegService;
import cn.ksb.minitxt.service.SelectService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.util.ArrayList;
import java.util.InputMismatchException;/*** 运行类*/
public class Run {private static Logger logger = LogManager.getLogger(Run.class);//创建记录日志对象public static void main(String[] args) {SelectService select = new SelectService();//创建选择对象RegService regFunction = new RegService();//创建注册对象LoginService loginFunction = new LoginService();//创建登录对象ArrayList<Novel> list = new ArrayList<>();//创建书本集合(存储武侠书本和言情书本)User user = new User();//创建统一用户类boolean flag = true;try {while (flag) {//循环选择select.printFunction();//打印选择内容switch (select.inputSelect()) {//判断选择结果case 1:loginFunction.loginAndReg(user, list);//打印登录功能方法break;case 2:regFunction.loginAndReg(user, list);//判断注册功能方法break;case 3:flag = false;//退出break;default:System.out.println("您的输入有误,没有该选项!");}System.out.println(ReaderCon.SEPARATE);}UserFileUtil util = new UserFileUtil();//循环结束后创建用户工具对象(包含IO流)util.writerObject(null);//每次全部执行完清空数据,不然下次运行时数据还在,如果想重复执行时之前注册的信息还在,就可以注释掉NovelFileUtil.writerObject(null);} catch (InputMismatchException e) {//输入错误异常System.out.println(ReaderCon.INPUTEX + "已自动帮您退出程序!");logger.error("由于主运行类" + Run.class.getName() + "类发生了" + e.getMessage() + "异常,已自动帮用户退出程序!");//记录异常信息} catch (Exception e) {//其他异常System.out.println(ReaderCon.EX + "已自动帮您退出程序!");logger.error("由于主运行类" + Run.class.getName() + "类发生了" + e.getMessage() + "异常,已自动帮用户退出程序!");//记录异常信息}System.out.println("\n" + ReaderCon.EXITRESULT);//结束语}
}
这篇关于Java进阶总结案例(小说阅读器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!