📄 bookparse.java
字号:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @author jerry
*
*/
public class BookParse {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String projectPath="./"; // 项目位置
String sourcePath=projectPath+"datasource/"; // 资源的位置
String outPath=projectPath+"target/"; // 解析后文件的存放位置
try{
String filePath= Tools.readFile("./parse.txt");
sourcePath +=filePath;
System.out.println("将要解析的文件为:"+sourcePath);
new BookParse().parseBookPack(sourcePath,outPath);
}catch(Exception e){
System.out.println("参数错误!");
e.printStackTrace();
}
}
/**
* 解析打包的文件
* 1. 取资源大小
* 2. 取书id号(前8位为书名id,后4位,小说为补充的0,杂志为期号id)
* 3. 是否小说('1'小说,'0'杂志)
* 4. 是否连载('1'连载,'0':小说为全本,杂志为默认)
* 5. 总章节
* 6. 中文书名
* 7. 循环取出打包的文件索引
* 位置1为封面索引,位置2为目录索引,后面为章节索引
* 8. 循环取文件长度,文件数据,输出对应的文件
* 位置1为封面长度,封面文件数据;
* 位置2为目录长度,目录文件数据;
* 后面为对应章节长度,章节文件数据
* 9. 图片个数 picNum
* 10. 根据 picNum 分别取图片名称,存入 List 对象 picNameList 列表中
* 11. 根据 picNum 分别取图片索引,存入 List 对象 picIndexList 列表中
* 12. 根据 picIndexList 分别取出图片长度,图片数据
* 再根据 picNameList 取出对应的图片名称,将其输出.
*
* @param bookPath
* @param outPath
* @throws Exception
*/
public void parseBookPack(String bookPath,String outPath) throws Exception{
// 读取文件数据
BufferedInputStream in = getStream(bookPath);
byte[] B = new byte[4];
byte[] b= new byte[2];
byte[] bc = new byte[1];
byte[] tb;
int sourceLen = 0; // 资源大小
String bookid=""; // 书id,取前8位
String type=""; // 是否小说/杂志
String bookname=""; // 书名
String issue=""; // 期号
String seria=""; // 连载属性
int t_chapter=0; // 总章节数
int len = 0; // 已读取的长度
int tlen=0; // 临时长度
// 1.资源大小
in.read(B);
sourceLen = Tools.getFromByte4(B);
len+=4;
System.out.println("55 lines 资源大小 => " + sourceLen+", len ::"+len);
// 2. 书id前8位
tb=new byte[8];
in.read(tb);
bookid=new String(tb);
len+=8;
System.out.println("61 lines 书 id => " + bookid+", len::"+len);
// 期号 后4位
in.read(B);
issue=new String(B);
len+=4;
System.out.println("61 lines 书 期号id => " + issue+", len::"+len);
// 是否小说/杂志
in.read(bc);
type=new String(bc);
len+=1;
String tp=type.equals("1")?"小说":"杂志";
System.out.println("67 lines 书类型 => " + tp +", len::"+len);
in.read(bc);
seria=new String(bc);
len+=1;
if("1".equals(type)){ // 小说取连载属性
tp=seria.equals("1")?"连载":"全本";
System.out.println("86 lines 连载属性 => " + tp+", len::"+len);
}
// 总章节数
in.read(B);
t_chapter=Tools.getFromByte4(B);
len+=4;
System.out.println("93 lines 总章节数 => " + t_chapter+", len::"+len);
// 打包章节数
in.read(B);
t_chapter=Tools.getFromByte4(B);
len+=4;
System.out.println("116 lines 打包章节数 => " + t_chapter+", len::"+len);
// 正文书名40字节:小说书名40字节,杂志书名20字节+期刊号20字节
String issueName="";
int ch;
if("1".equals(type)){
tb=new byte[40];
in.read(tb);
bookname=new String(tb);
bookname=bookname.trim();
ch=bookname.indexOf("0");
bookname=ch>0?bookname.substring(0, ch):bookname;
}else{
tb=new byte[20];
in.read(tb);
bookname=new String(tb);
bookname=bookname.trim();
tb=new byte[20];
in.read(tb);
issueName=new String(tb);
issueName=issueName.trim();
}
len+=40;
System.out.println("102 lines 正文书名 => " + bookname +", len::"+len);
tb=new byte[40];
in.read(tb);
bookname=new String(tb);
bookname=bookname.trim();
ch=bookname.indexOf("0");
bookname=ch>0?bookname.substring(0, ch):bookname;
System.out.println("137 lines 打包的章节 ::"+bookname);
if("0".equals(type)){ // 杂志取期号索引
System.out.println("140 lines 期号 => " + issueName+", len::"+len);
}
// 章节名称索引和章节数据索引
List<Integer> c_name_list=new ArrayList<Integer>(); // 存放章节名称
List<Integer> c_data_index_list=new ArrayList<Integer>(); // 存放章节正文索引列表
// 取起始章节号
in.read(B);
int begCH=tlen=Tools.getFromByte4(B);
len+=4;
// 取末尾章节号
in.read(B);
int endCH=tlen=Tools.getFromByte4(B);
len+=4;
for(int i=begCH;i<=endCH;i++){ // 取章节名称
System.out.println("116 lines 第 "+(i+1)+" 章名称 => " + tlen+", len::"+len);
c_name_list.add(i);
}
// 取封面索引, 取目录索引, 正文索引
for(int i=0;i<t_chapter+2;i++){ // t_chapter+2 是因为有封面和目录
in.read(B);
tlen=Tools.getFromByte4(B);
len+=4;
System.out.println("124 lines 第 "+(i+1)+" 章正文索引 => " + tlen+", len::"+len);
c_data_index_list.add(tlen);
}
// 取第t_chapter+1章的正文索引
in.read(B);
tlen=Tools.getFromByte4(B);
len+=4;
Integer chapterN=tlen;
System.out.println("----------- chapterN ==>"+chapterN);
// 取图片个数
in.read(b);
int picNum=Tools.getFromByte2(b);
len+=2;
System.out.println("----------- 图片个数 ==>"+tlen);
// 图片信息
List<String> picNameList=new ArrayList<String>(); // 存放图片名称列表
List<Integer> picIndexList=new ArrayList<Integer>();// 存放图片索引列表
// 图片名称
for(int i=0;i<picNum;i++){
tb=new byte[20];
in.read(tb);
len+=20;
String cont=new String(tb);
cont=cont.trim();
ch=cont.indexOf("0");
cont=ch>0?cont.substring(0, ch):cont;
picNameList.add(cont);
System.out.println("179 lines 第 "+(i+1)+" 个图片名称 ==> " + cont+", len::"+len+", 没有截取名称 ==>"+cont);
}
// 图片索引
for(int i=0;i<picNum;i++){
in.read(B);
len+=4;
int index=Tools.getFromByte4(B);
picIndexList.add(index);
System.out.println("187 lines 第 "+(i+1)+" 个图片索引 ==> " + index+", len::"+len);
}
// 取第n+1张图片的索引 (为虚拟的)
in.read(B);
len+=4;
int picNIndex=Tools.getFromByte4(B);
System.out.println("=========================================");
System.out.println(" picNIndex ==>"+picNIndex+", sourceLen ==>"+sourceLen);
// 取正文长度和正文数据
for(int i=0;i<c_data_index_list.size();i++){
String fileName=""; // 输出的文件名
// 正文数据
// 判断是否为最后打包的正文
String cont="";
if(i==c_data_index_list.size()-1){ // 取最后打包的章节
tlen=chapterN-c_data_index_list.get(i);
tb=new byte[tlen];
in.read(tb);
len+=tlen;
cont=new String(tb);
if("0".equals(type)) // 杂志的封面
fileName=c_name_list.get(i-2)+""; //"_"+issue+"_"+c_name_list.get(i-2);
else // 小说封面
fileName=c_name_list.get(i-2)+""; //"_"+c_name_list.get(i-2);
fileName+= ".html";
}else{ // 不取最后打包的章节
tlen=c_data_index_list.get(i+1)-c_data_index_list.get(i);
tb=new byte[tlen];
in.read(tb);
len+=tlen;
cont=new String(tb);
// 输出正文内容
if(i==0)
if("0".equals(type)) // 杂志的封面
fileName="cover"; //"_"+issue;
else // 小说封面
fileName="cover"; //"";
else if(i==1)
if("0".equals(type)) // 杂志的目录
fileName="index"; //"_"+issue+"_0";
else // 小说目录
fileName="index"; //"_0";
else
if("0".equals(type)) // 杂志的正文
fileName=c_name_list.get(i-2)+""; //"_"+issue+"_"+c_name_list.get(i-2);
else // 小说正文
fileName=c_name_list.get(i-2)+""; //"_"+c_name_list.get(i-2);
fileName+= ".html";
}
Tools.printFile(outPath+fileName,cont.getBytes());
}
// 图片长度,图片数据, 输出图片
for(int i=0;i<picIndexList.size();i++){
String fileName="";
// 图片数据
// 判断是否为最后一张图片
if(i==picIndexList.size()-1){
tlen=picNIndex-picIndexList.get(i);
}else{
tlen=picIndexList.get(i+1)-picIndexList.get(i);
}
tb=new byte[tlen];
in.read(tb);
len+=tlen;
fileName+= picNameList.get(i);
System.out.println("202 lines 第 "+(i+1)+" 个图片名称 ==> " + fileName+", len::"+len+", 图片长度 ==>"+tlen);
Tools.printFile(outPath+fileName,tb);
}
}
public BufferedInputStream getStream(String filename) throws Exception{
BufferedInputStream in = null;
File inFile = new File(filename);
in = new BufferedInputStream(new FileInputStream(inFile));
return in;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -