第六章、epub文件处理 -- 解析container文件与.opf文件
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
第六章、epub文件處理?--?解析container文件與.opf文件
?
這一章我們會接著第三章結(jié)尾介紹的FBReaderApp類的openBookInternal繼續(xù),開始介紹解析container文件與.opf文件。
這一章中會涉及到第二章、第四章、第五章中介紹的內(nèi)容,大家可以互相參照,加深理解
首先,我們來回顧下第四章“epub文件處理?--?epub文件內(nèi)部組成”的內(nèi)容。我們在第四章中曾經(jīng)介紹過,epub文內(nèi)部包含的文件包括“container.xml文件、.opf文件、.ncx文件、.xhtml文件”。這些文件都是被壓縮過的xml文件,而在這些不同的xml文件中包含著不同的標(biāo)簽,每種標(biāo)簽又都代表著不同的信息。為了對每種xml文件的標(biāo)簽作統(tǒng)一處理,FBReader程序?qū)γ糠N文件都設(shè)置了對應(yīng)的類。每種類就專門處理來對應(yīng)的xml文件里面的標(biāo)簽。
ContainerFileReader類對應(yīng)container.xml文件;OEBBookReader類對應(yīng).opf文件; NCXReader類對應(yīng).ncx文件文件;XHTMLReader類對應(yīng).xhtml文件。
PS:這些類都是ZLXMLReaderAdapter抽象類的子類,本章會涉及到ContainerFileReader類與OEBBookReader類
我們在第四章中還曾經(jīng)分別介紹過container文件與.opf文件分別的作用。
container文件的“作用就是標(biāo)明了.opf文件的位置”;.opf文件則描述了epub書籍的元信息、epub文件內(nèi)部對應(yīng)不同章節(jié)對應(yīng)的文件的位置以及每個章節(jié)出現(xiàn)的先后次序。
我們這一章解析這兩種文件,就是為了獲取這些信息。
在介紹解析流程之前,我們還需要再回顧下解析xml文件的三個核心類。這個部分內(nèi)容,我們曾經(jīng)在第二章“解析資源文件”中介紹過。當(dāng)時,我們是這么介紹的:“
繼續(xù)回到解析xml文件的核心類ZMLZMLProcessor、ZLXMLParser、ZLXMLReader。
這三個核心類的調(diào)用順序一般是這樣的:
?1、ZLXMLReaderAdapter抽象類的子類(ResourceTreeReader類)里面的read方法調(diào)用ZLXMLProcessor類的read方法
2、ZLXMLProcessor類的read方法通過AndroidAssetsFile類(ZLResourceFile類的子類)的getInputStream方法獲取一個針對資源文件的字節(jié)流類(AssetInputStream類),并以這個字節(jié)流類為參數(shù)初始化了一個針對資源文件的字符流類。接著,就調(diào)用了ZLXMLParser類的doIt方法。
3、?ZLXMLParser類的doIt方法利用字符流類將文件轉(zhuǎn)換成一個char數(shù)組。再利用for循環(huán)迭代byte數(shù)組的過程中,doIt方法又反過來調(diào)用ZLXMLReader接口實現(xiàn)類(ResourceTreeReader類)的startElementHandler與endElementHandler方法對byte數(shù)組中元素所代表的不同節(jié)點進行操作。
?
請注意,上面這段話標(biāo)紅的部分,這些部分在解析epub內(nèi)部文件的流程中已經(jīng)不適用了。
1、ZLXMLReaderAdapter抽象類的子類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)里面的read方法調(diào)用ZLXMLProcessor類的read方法
2、ZLXMLProcessor類的read方法通過ZLZipEntryFile類的getInputStream方法和ZLZipEntryFile類對應(yīng)的LocalFileHeader類獲取一個針對epub內(nèi)部xml文件的字節(jié)流類(ZipInputStream類),并以這個字節(jié)流類為參數(shù)初始化了一個針對資源文件的字符流類。接著,就調(diào)用了ZLXMLParser類的doIt方法。
3、?ZLXMLParser類的doIt方法利用字符流類將文件轉(zhuǎn)換成一個char數(shù)組(第五章用一整個章節(jié)介紹了這個轉(zhuǎn)換的流程)。再利用for循環(huán)迭代byte數(shù)組的過程中,doIt方法又反過來調(diào)用ZLXMLReader接口實現(xiàn)類(ResourceTreeReader類)的startElementHandler與endElementHandler方法對byte數(shù)組中元素所代表的不同節(jié)點進行操作。
首先,“ZLXMLReaderAdapter抽象類的子類”已經(jīng)不再是那個ResourceTreeReader類了,而是專門對應(yīng)epub內(nèi)部各種xml文件的一個類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)。
PS:ResourceTreeReader類是程序?qū)iT為處理資源文件內(nèi)部的標(biāo)簽而創(chuàng)建的類
其次,程序在解析epub內(nèi)部xml文件的時候,不會去獲取“針對資源文件的字節(jié)流類”,而是會通過調(diào)用ZLZipEntryFile類的getInputStream方法獲取針對epub內(nèi)部xml文件的字節(jié)流類(ZipInputStream類)。相對得,之后也會以這個字節(jié)流類來獲得對應(yīng)的字符流類。
PS:ZLZipEntryFile類的getInputStream方法的具體處理流程我們曾經(jīng)用了第五章“XML文件處理?--?解壓”一整章來作介紹
好了,下面我們就正式開始解析流程。
?
FBReaderApp類的openBookInternal方法中會調(diào)用BookModel類的createModel方法。
crateModel方法,會調(diào)用PluginCollection類的getPlugin方法
getPlugin方法調(diào)用了所有FormatPlugin抽象類子類的acceptsFile方法,這個方法其實就是比較了Book類中File屬性指向的File類的myExtension屬性(這個屬性的賦值我們在第三章“獲取書籍信息”中介紹過),如果myExtension屬性代碼內(nèi)置的變量相同,getPlugin方法就會返回當(dāng)前的FormatPlugin抽象類子類。而在處理epub文件時,代碼會返回OEBPlugin類。
OEBPlugin類readModel方法
獲得了OEBPlugin類之后,代碼就會調(diào)用該類中的readModel方法。
readModel方法調(diào)用了兩個方法:OEBPlugin類的getOpfFile方法與OEBBookReader類readBook方法
OEBPlugin類的getOpfFile方法:
getOpfFile方法一共有三步:第一步 ? ?
調(diào)用ZLFile類的createFile方法
這個方法的參數(shù)oebFile參數(shù)是Book類的File屬性(這個屬性的賦值過程在第三章“獲取書籍信息”介紹過),最終這個方法會返回一個代表container.xml文件的ZLZipEntryFile類。
我們曾經(jīng)在第二章“解析資源文件”中介紹過:“ZLZipEntryFile類用來處理epub文件內(nèi)部的xml文件”。也曾經(jīng)在第四章“epub文件處理?--?epub文件內(nèi)部組成”介紹過container.xml文件,這個文件的作用就是“標(biāo)明了.opf文件的位置”。
我們從代碼中可以看到,代表container.xml文件的ZLZipEntryFile會包含兩個屬性(85行):一個代表epub文件的ZLPhysicalFile類,一個代表epub內(nèi)部xml文件名種子的String變量(在這里就是)。
第二步
ContainerFileReader類的read方法。
看到這個方法,你應(yīng)該會記起這一章開頭介紹的“解析epub內(nèi)部文件的流程”吧。
1、ZLXMLReaderAdapter抽象類的子類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)里面的read方法調(diào)用ZLXMLProcessor類的read方法
2、ZLXMLProcessor類的read方法通過ZLZipEntryFile類的getInputStream方法和ZLZipEntryFile類對應(yīng)的LocalFileHeader類獲取一個針對epub內(nèi)部xml文件的字節(jié)流類(ZipInputStream類),并以這個字節(jié)流類為參數(shù)初始化了一個針對資源文件的字符流類。接著,就調(diào)用了ZLXMLParser類的doIt方法。
3、?ZLXMLParser類的doIt方法利用字符流類將文件轉(zhuǎn)換成一個char數(shù)組(第五章用一整個章節(jié)介紹了這個轉(zhuǎn)換的流程)。再利用for循環(huán)迭代byte數(shù)組的過程中,doIt方法又反過來調(diào)用ZLXMLReader接口實現(xiàn)類(ResourceTreeReader類)的startElementHandler與endElementHandler方法對byte數(shù)組中元素所代表的不同節(jié)點進行操作。
在這個解析流程中, .opf 文件的位置信息會被存儲到 ContainerFileReader 類的 myRootPath 屬性( 35 行)
第三步
代碼以包含.opf的位置信息的String為參數(shù)又調(diào)用了ZLFile類的createFile方法,這個方法會返回代表.opf文件的ZLZipEntryFile類,獲取這個類之后,代碼會進入OEBBookReader類readBook方法
OEBBookReader類readBook方法:
這個方法分為兩步:第一步、更新myHtmlFileNames屬性;第二步、for循環(huán)迭代myHtmlFileNames屬性指向的ArrayList,解析xhtml文件。第一步
更新myHtmlFileNames屬性
OEBBookReader類的read方法更新了myHtmlFileNames屬性。
OEBBookReader類的read方法用讓代碼進入了解析xml文件的流程:
1、ZLXMLReaderAdapter抽象類的子類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)里面的read方法調(diào)用ZLXMLProcessor類的read方法
2、ZLXMLProcessor類的read方法通過ZLZipEntryFile類的getInputStream方法和ZLZipEntryFile類對應(yīng)的LocalFileHeader類獲取一個針對epub內(nèi)部xml文件的字節(jié)流類(ZipInputStream類),并以這個字節(jié)流類為參數(shù)初始化了一個針對資源文件的字符流類。接著,就調(diào)用了ZLXMLParser類的doIt方法。
3、?ZLXMLParser類的doIt方法利用字符流類將文件轉(zhuǎn)換成一個char數(shù)組(第五章用一整個章節(jié)介紹了這個轉(zhuǎn)換的流程)。再利用for循環(huán)迭代char數(shù)組的過程中,doIt方法又反過來調(diào)用ZLXMLReader接口實現(xiàn)類(ResourceTreeReader類)的startElementHandler與endElementHandler方法對byte數(shù)組中元素所代表的不同節(jié)點進行操作。
我們曾經(jīng)在第四章“epub文件處理?--?epub文件內(nèi)部組成”中介紹過.opf文件中的“manifest節(jié)點的作用是描述epub文件內(nèi)部對應(yīng)不同章節(jié)對應(yīng)的文件的位置”。
我們現(xiàn)在就是要把這些位置信息存儲到myHtmlFileNames屬性指向的ArrayList中。而這個工作是OEBBookReader類的startElementHandler方法中完成的。
第二步
for循環(huán)迭代myHtmlFileNames屬性指向的ArrayList,解析xhtml文件
ZLFile類的createFileByPath方法會生成代表xhtml文件的ZLZipEntryFile類。之后XHTMLReader類的readFile方法會開始對xhtml文件的解析。
XHTMLReader類的readFile方法會調(diào)用本類的read方法。這個方法又會讓代碼進入解析xml文件的流程。這個流程我們在本章中已經(jīng)多次遇到了。走完這個流程,我們就會得到一個有xml文件轉(zhuǎn)換成的char數(shù)組。代碼循環(huán)迭代這個char數(shù)組,調(diào)用XHTMLReader類的startElementHandler與endElementHandler方法對byte數(shù)組中元素所代表的不同節(jié)點進行操作。
對xhtml文件中各節(jié)點的操作比container.xml與.opf文件的操作要復(fù)雜很多,我們將用兩個章節(jié)來介紹。
轉(zhuǎn)載于:https://my.oschina.net/u/938986/blog/335878
總結(jié)
以上是生活随笔為你收集整理的第六章、epub文件处理 -- 解析container文件与.opf文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: div border-radius
- 下一篇: Oracle10g下载地址