第六章、epub文件處理 -- 解析container文件與.opf文件

第六章、epub文件處理 -- 解析container文件與.opf文件

 

這一章咱們會接着第三章結尾介紹的FBReaderApp類的openBookInternal繼續,開始介紹解析container文件與.opf文件。 html

這一章中會涉及到第二章、第四章、第五章中介紹的內容,你們能夠互相參照,加深理解 數組

首先,咱們來回顧下第四章「epub文件處理 -- epub文件內部組成」的內容。咱們在第四章中曾經介紹過,epub文內部包含的文件包括「container.xml文件、.opf文件、.ncx文件、.xhtml文件」。這些文件都是被壓縮過的xml文件,而在這些不一樣的xml文件中包含着不一樣的標籤,每種標籤又都表明着不一樣的信息。爲了對每種xml文件的標籤做統一處理,FBReader程序對每種文件都設置了對應的類。每種類就專門處理來對應的xml文件裏面的標籤。 spa


ContainerFileReader類對應container.xml文件;OEBBookReader類對應.opf文件; NCXReader類對應.ncx文件文件;XHTMLReader類對應.xhtml文件。 orm

PS:這些類都是ZLXMLReaderAdapter抽象類的子類,本章會涉及到ContainerFileReader類與OEBBookReader xml

咱們在第四章中還曾經分別介紹過container文件與.opf文件分別的做用。 htm

container文件的「做用就是標明瞭.opf文件的位置」;.opf文件則描述了epub書籍的元信息、epub文件內部對應不一樣章節對應的文件的位置以及每一個章節出現的前後次序。 接口

咱們這一章解析這兩種文件,就是爲了獲取這些信息。 ip



在介紹解析流程以前,咱們還須要再回顧下解析xml文件的三個核心類。這個部份內容,咱們曾經在第二章「解析資源文件」中介紹過。當時,咱們是這麼介紹的:「 資源

繼續回到解析xml文件的核心類ZMLZMLProcessorZLXMLParserZLXMLReader get

這三個核心類的調用順序通常是這樣的:

 1ZLXMLReaderAdapter抽象類的子類ResourceTreeReader類)裏面的read方法調用ZLXMLProcessor類的read方法

2ZLXMLProcessor類的read方法經過AndroidAssetsFile類(ZLResourceFile類的子類)getInputStream方法獲取一個針對資源文件的字節流類(AssetInputStream類),並以這個字節流類爲參數初始化了一個針對資源文件的字符流類。接着,就調用了ZLXMLParser類的doIt方法。

3、 ZLXMLParser類的doIt方法利用字符流類將文件轉換成一個char數組。再利用for循環迭代byte數組的過程當中,doIt方法又反過來調用ZLXMLReader接口實現類(ResourceTreeReader類)的startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。

 

請注意,上面這段話標紅的部分,這些部分在解析epub內部文件的流程中已經不適用了。

1ZLXMLReaderAdapter抽象類的子類ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)裏面的read方法調用ZLXMLProcessor類的read方法

2ZLXMLProcessor類的read方法經過ZLZipEntryFilegetInputStream方法和ZLZipEntryFile類對應的LocalFileHeader獲取一個針對epub內部xml文件的字節流類(ZipInputStream類),並以這個字節流類爲參數初始化了一個針對資源文件的字符流類。接着,就調用了ZLXMLParser類的doIt方法。

3、 ZLXMLParser類的doIt方法利用字符流類將文件轉換成一個char數組(第五章用一整個章節介紹了這個轉換的流程)。再利用for循環迭代byte數組的過程當中,doIt方法又反過來調用ZLXMLReader接口實現類(ResourceTreeReader類)的startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。

首先,「ZLXMLReaderAdapter抽象類的子類」已經再也不是那個ResourceTreeReader類了,而是專門對應epub內部各類xml文件的一個類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)。

PSResourceTreeReader類是程序專門爲處理資源文件內部的標籤而建立的類

其次,程序在解析epub內部xml文件的時候,不會去獲取「針對資源文件的字節流類」,而是會經過調用ZLZipEntryFile類的getInputStream方法獲取針對epub內部xml文件的字節流類(ZipInputStream類)。相對得,以後也會以這個字節流類來得到對應的字符流類。

PSZLZipEntryFile類的getInputStream方法的具體處理流程咱們曾經用了第五章「XML文件處理 -- 解壓」一整章來做介紹



好了,下面咱們就正式開始解析流程。

 

FBReaderApp類的openBookInternal方法中會調用BookModel類的createModel方法。


crateModel方法,會調用PluginCollection類的getPlugin方法

getPlugin方法調用了全部FormatPlugin抽象類子類的acceptsFile方法,這個方法其實就是比較了Book類中File屬性指向的File類的myExtension屬性(這個屬性的賦值咱們在第三章「獲取書籍信息」中介紹過),若是myExtension屬性代碼內置的變量相同,getPlugin方法就會返回當前的FormatPlugin抽象類子類。而在處理epub文件時,代碼會返回OEBPlugin類。




OEBPluginreadModel方法

得到了OEBPlugin類以後,代碼就會調用該類中的readModel方法。



readModel方法調用了兩個方法:OEBPlugin類的getOpfFile方法與OEBBookReaderreadBook方法



OEBPlugin類的getOpfFile方法:

getOpfFile方法一共有三步:

第一步    

調用ZLFile類的createFile方法

這個方法的參數oebFile參數是Book類的File屬性(這個屬性的賦值過程在第三章「獲取書籍信息」介紹過),最終這個方法會返回一個表明container.xml文件的ZLZipEntryFile類。

咱們曾經在第二章「解析資源文件」中介紹過:「ZLZipEntryFile類用來處理epub文件內部的xml文件」。也曾經在第四章「epub文件處理 -- epub文件內部組成」介紹過container.xml文件,這個文件的做用就是「標明瞭.opf文件的位置」。

咱們從代碼中能夠看到,表明container.xml文件的ZLZipEntryFile會包含兩個屬性(85行):一個表明epub文件的ZLPhysicalFile類,一個表明epub內部xml文件名種子的String變量(在這裏就是)。


第二步

ContainerFileReader類的read方法。

看到這個方法,你應該會記起這一章開頭介紹的「解析epub內部文件的流程」吧。

1ZLXMLReaderAdapter抽象類的子類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)裏面的read方法調用ZLXMLProcessor類的read方法

2ZLXMLProcessor類的read方法經過ZLZipEntryFile類的getInputStream方法和ZLZipEntryFile類對應的LocalFileHeader類獲取一個針對epub內部xml文件的字節流類(ZipInputStream類),並以這個字節流類爲參數初始化了一個針對資源文件的字符流類。接着,就調用了ZLXMLParser類的doIt方法。

3、 ZLXMLParser類的doIt方法利用字符流類將文件轉換成一個char數組(第五章用一整個章節介紹了這個轉換的流程)。再利用for循環迭代byte數組的過程當中,doIt方法又反過來調用ZLXMLReader接口實現類(ResourceTreeReader類)的startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。

           在這個解析流程中, .opf 文件的位置信息會被存儲到 ContainerFileReader 類的 myRootPath 屬性( 35 行)



第三步

代碼以包含.opf的位置信息的String爲參數又調用了ZLFile類的createFile方法,這個方法會返回表明.opf文件的ZLZipEntryFile類,獲取這個類以後,代碼會進入OEBBookReaderreadBook方法


OEBBookReaderreadBook方法:

這個方法分爲兩步:第一步、更新myHtmlFileNames屬性;第二步、for循環迭代myHtmlFileNames屬性指向的ArrayList,解析xhtml文件。

第一步

更新myHtmlFileNames屬性

OEBBookReader類的read方法更新了myHtmlFileNames屬性。


OEBBookReader類的read方法用讓代碼進入瞭解析xml文件的流程:

1ZLXMLReaderAdapter抽象類的子類(ContainerFileReader類、OEBBookReader類、NCXReader類、XHTMLReader類中的一種)裏面的read方法調用ZLXMLProcessor類的read方法

2ZLXMLProcessor類的read方法經過ZLZipEntryFile類的getInputStream方法和ZLZipEntryFile類對應的LocalFileHeader類獲取一個針對epub內部xml文件的字節流類(ZipInputStream類),並以這個字節流類爲參數初始化了一個針對資源文件的字符流類。接着,就調用了ZLXMLParser類的doIt方法。

3、 ZLXMLParser類的doIt方法利用字符流類將文件轉換成一個char數組(第五章用一整個章節介紹了這個轉換的流程)。再利用for循環迭代char數組的過程當中,doIt方法又反過來調用ZLXMLReader接口實現類(ResourceTreeReader類)的startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。

咱們曾經在第四章「epub文件處理 -- epub文件內部組成」中介紹過.opf文件中的「manifest節點的做用是描述epub文件內部對應不一樣章節對應的文件的位置」。


咱們如今就是要把這些位置信息存儲到myHtmlFileNames屬性指向的ArrayList中。而這個工做是OEBBookReader類的startElementHandler方法中完成的。


第二步

for循環迭代myHtmlFileNames屬性指向的ArrayList,解析xhtml文件

ZLFile類的createFileByPath方法會生成表明xhtml文件的ZLZipEntryFile類。以後XHTMLReader類的readFile方法會開始對xhtml文件的解析。


XHTMLReader類的readFile方法會調用本類的read方法。這個方法又會讓代碼進入解析xml文件的流程。這個流程咱們在本章中已經屢次遇到了。走完這個流程,咱們就會獲得一個有xml文件轉換成的char數組。代碼循環迭代這個char數組,調用XHTMLReader類的startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。


xhtml文件中各節點的操做比container.xml.opf文件的操做要複雜不少,咱們將用兩個章節來介紹。

相關文章
相關標籤/搜索