|
|
|
@ -11,7 +11,6 @@ import xyz.fycz.myreader.greendao.entity.Chapter; |
|
|
|
|
import xyz.fycz.myreader.greendao.service.ChapterService; |
|
|
|
|
import xyz.fycz.myreader.util.IOUtils; |
|
|
|
|
import xyz.fycz.myreader.util.StringHelper; |
|
|
|
|
import xyz.fycz.myreader.util.utils.Charset; |
|
|
|
|
import xyz.fycz.myreader.util.utils.FileUtils; |
|
|
|
|
import xyz.fycz.myreader.util.utils.RxUtils; |
|
|
|
|
|
|
|
|
@ -21,6 +20,8 @@ import java.util.List; |
|
|
|
|
import java.util.regex.Matcher; |
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
import static xyz.fycz.myreader.util.utils.FileUtils.BLANK; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Created by newbiechen on 17-7-1. |
|
|
|
|
* 问题: |
|
|
|
@ -62,201 +63,6 @@ public class LocalPageLoader extends PageLoader { |
|
|
|
|
this.mChapterService = mChapterService; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*private List<BookChapterBean> convertTxtChapter(List<BookChapterBean> bookChapters) { |
|
|
|
|
List<BookChapterBean> txtChapters = new ArrayList<>(bookChapters.size()); |
|
|
|
|
for (BookChapterBean bean : bookChapters) { |
|
|
|
|
BookChapterBean chapter = new BookChapterBean(); |
|
|
|
|
chapter.title = bean.getTitle(); |
|
|
|
|
chapter.start = bean.getStart(); |
|
|
|
|
chapter.end = bean.getEnd(); |
|
|
|
|
txtChapters.add(chapter); |
|
|
|
|
} |
|
|
|
|
return txtChapters; |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 未完成的部分: |
|
|
|
|
* 1. 序章的添加 |
|
|
|
|
* 2. 章节存在的书本的虚拟分章效果 |
|
|
|
|
*/ |
|
|
|
|
/*public List<Chapter> loadChapters() throws IOException { |
|
|
|
|
mBookFile = new File(mCollBook.getChapterUrl()); |
|
|
|
|
//获取文件编码
|
|
|
|
|
mCharset = FileUtils.getFileEncode(mBookFile.getAbsolutePath()); |
|
|
|
|
List<Chapter> chapters = new ArrayList<>(); |
|
|
|
|
RandomAccessFile bookStream = null; |
|
|
|
|
boolean hasChapter = false; |
|
|
|
|
//获取文件流
|
|
|
|
|
bookStream = new RandomAccessFile(mBookFile, "r"); |
|
|
|
|
//寻找匹配文章标题的正则表达式,判断是否存在章节名
|
|
|
|
|
hasChapter = checkChapterType(bookStream); |
|
|
|
|
//加载章节
|
|
|
|
|
byte[] buffer = new byte[BUFFER_SIZE]; |
|
|
|
|
//获取到的块起始点,在文件中的位置
|
|
|
|
|
long curOffset = 0; |
|
|
|
|
//block的个数
|
|
|
|
|
int blockPos = 0; |
|
|
|
|
//读取的长度
|
|
|
|
|
int length; |
|
|
|
|
|
|
|
|
|
//获取文件中的数据到buffer,直到没有数据为止
|
|
|
|
|
while ((length = bookStream.read(buffer, 0, buffer.length)) > 0) { |
|
|
|
|
++blockPos; |
|
|
|
|
//如果存在Chapter
|
|
|
|
|
if (hasChapter) { |
|
|
|
|
//将数据转换成String
|
|
|
|
|
String blockContent = new String(buffer, 0, length, mCharset); |
|
|
|
|
//当前Block下使过的String的指针
|
|
|
|
|
int seekPos = 0; |
|
|
|
|
//进行正则匹配
|
|
|
|
|
Matcher matcher = mChapterPattern.matcher(blockContent); |
|
|
|
|
//如果存在相应章节
|
|
|
|
|
while (matcher.find()) { |
|
|
|
|
//获取匹配到的字符在字符串中的起始位置
|
|
|
|
|
int chapterStart = matcher.start(); |
|
|
|
|
|
|
|
|
|
//如果 seekPos == 0 && nextChapterPos != 0 表示当前block处前面有一段内容
|
|
|
|
|
//第一种情况一定是序章 第二种情况可能是上一个章节的内容
|
|
|
|
|
if (seekPos == 0 && chapterStart != 0) { |
|
|
|
|
//获取当前章节的内容
|
|
|
|
|
String chapterContent = blockContent.substring(seekPos, chapterStart); |
|
|
|
|
//设置指针偏移
|
|
|
|
|
seekPos += chapterContent.length(); |
|
|
|
|
|
|
|
|
|
//如果当前对整个文件的偏移位置为0的话,那么就是序章
|
|
|
|
|
if (curOffset == 0) { |
|
|
|
|
//创建序章
|
|
|
|
|
Chapter preChapter = new Chapter(); |
|
|
|
|
preChapter.setTitle("序章"); |
|
|
|
|
preChapter.setStart(0); |
|
|
|
|
preChapter.setEnd(chapterContent.getBytes(mCharset).length); //获取String的byte值,作为最终值
|
|
|
|
|
|
|
|
|
|
//如果序章大小大于30才添加进去
|
|
|
|
|
if (preChapter.getEnd() - preChapter.getStart() > 30) { |
|
|
|
|
chapters.add(preChapter); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//创建当前章节
|
|
|
|
|
Chapter curChapter = new Chapter(); |
|
|
|
|
curChapter.setTitle(matcher.group()); |
|
|
|
|
curChapter.setStart(preChapter.getEnd()); |
|
|
|
|
chapters.add(curChapter); |
|
|
|
|
} |
|
|
|
|
//否则就block分割之后,上一个章节的剩余内容
|
|
|
|
|
else { |
|
|
|
|
//获取上一章节
|
|
|
|
|
Chapter lastChapter = chapters.get(chapters.size() - 1); |
|
|
|
|
//将当前段落添加上一章去
|
|
|
|
|
lastChapter.setEnd(lastChapter.getEnd() + chapterContent.getBytes(mCharset).length); |
|
|
|
|
|
|
|
|
|
//如果章节内容太小,则移除
|
|
|
|
|
if (lastChapter.getEnd() - lastChapter.getStart() < 30) { |
|
|
|
|
chapters.remove(lastChapter); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//创建当前章节
|
|
|
|
|
Chapter curChapter = new Chapter(); |
|
|
|
|
curChapter.setTitle(matcher.group()); |
|
|
|
|
curChapter.setStart(lastChapter.getEnd()); |
|
|
|
|
chapters.add(curChapter); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
//是否存在章节
|
|
|
|
|
if (chapters.size() != 0) { |
|
|
|
|
//获取章节内容
|
|
|
|
|
String chapterContent = blockContent.substring(seekPos, matcher.start()); |
|
|
|
|
seekPos += chapterContent.length(); |
|
|
|
|
|
|
|
|
|
//获取上一章节
|
|
|
|
|
Chapter lastChapter = chapters.get(chapters.size() - 1); |
|
|
|
|
lastChapter.setEnd(lastChapter.getStart() + chapterContent.getBytes(mCharset).length); |
|
|
|
|
|
|
|
|
|
//如果章节内容太小,则移除
|
|
|
|
|
if (lastChapter.getEnd() - lastChapter.getStart() < 30) { |
|
|
|
|
chapters.remove(lastChapter); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//创建当前章节
|
|
|
|
|
Chapter curChapter = new Chapter(); |
|
|
|
|
curChapter.setTitle(matcher.group()); |
|
|
|
|
curChapter.setStart(lastChapter.getEnd()); |
|
|
|
|
chapters.add(curChapter); |
|
|
|
|
} |
|
|
|
|
//如果章节不存在则创建章节
|
|
|
|
|
else { |
|
|
|
|
Chapter curChapter = new Chapter(); |
|
|
|
|
curChapter.setTitle(matcher.group()); |
|
|
|
|
curChapter.setStart(0); |
|
|
|
|
chapters.add(curChapter); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//进行本地虚拟分章
|
|
|
|
|
else { |
|
|
|
|
//章节在buffer的偏移量
|
|
|
|
|
int chapterOffset = 0; |
|
|
|
|
//当前剩余可分配的长度
|
|
|
|
|
int strLength = length; |
|
|
|
|
//分章的位置
|
|
|
|
|
int chapterPos = 0; |
|
|
|
|
|
|
|
|
|
while (strLength > 0) { |
|
|
|
|
++chapterPos; |
|
|
|
|
//是否长度超过一章
|
|
|
|
|
if (strLength > MAX_LENGTH_WITH_NO_CHAPTER) { |
|
|
|
|
//在buffer中一章的终止点
|
|
|
|
|
int end = length; |
|
|
|
|
//寻找换行符作为终止点
|
|
|
|
|
for (int i = chapterOffset + MAX_LENGTH_WITH_NO_CHAPTER; i < length; ++i) { |
|
|
|
|
if (buffer[i] == Charset.BLANK) { |
|
|
|
|
end = i; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Chapter chapter = new Chapter(); |
|
|
|
|
chapter.setTitle("第" + blockPos + "章" + "(" + chapterPos + ")"); |
|
|
|
|
chapter.setStart(curOffset + chapterOffset + 1); |
|
|
|
|
chapter.setEnd(curOffset + end); |
|
|
|
|
chapters.add(chapter); |
|
|
|
|
//减去已经被分配的长度
|
|
|
|
|
strLength = strLength - (end - chapterOffset); |
|
|
|
|
//设置偏移的位置
|
|
|
|
|
chapterOffset = end; |
|
|
|
|
} else { |
|
|
|
|
Chapter chapter = new Chapter(); |
|
|
|
|
chapter.setTitle("第" + blockPos + "章" + "(" + chapterPos + ")"); |
|
|
|
|
chapter.setStart(curOffset + chapterOffset + 1); |
|
|
|
|
chapter.setEnd(curOffset + length); |
|
|
|
|
chapters.add(chapter); |
|
|
|
|
strLength = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//block的偏移点
|
|
|
|
|
curOffset += length; |
|
|
|
|
|
|
|
|
|
if (hasChapter) { |
|
|
|
|
//设置上一章的结尾
|
|
|
|
|
Chapter lastChapter = chapters.get(chapters.size() - 1); |
|
|
|
|
lastChapter.setEnd(curOffset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//当添加的block太多的时候,执行GC
|
|
|
|
|
if (blockPos % 15 == 0) { |
|
|
|
|
System.gc(); |
|
|
|
|
System.runFinalization(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
IOUtils.close(bookStream); |
|
|
|
|
System.gc(); |
|
|
|
|
System.runFinalization(); |
|
|
|
|
return chapters; |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 未完成的部分: |
|
|
|
|
* 1. 序章的添加 |
|
|
|
@ -390,7 +196,7 @@ public class LocalPageLoader extends PageLoader { |
|
|
|
|
int end = length; |
|
|
|
|
//寻找换行符作为终止点
|
|
|
|
|
for (int i = chapterOffset + MAX_LENGTH_WITH_NO_CHAPTER; i < length; ++i) { |
|
|
|
|
if (buffer[i] == Charset.BLANK) { |
|
|
|
|
if (buffer[i] == BLANK) { |
|
|
|
|
end = i; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|