本文介紹了在將大量文件數(shù)據(jù)寫入XML時(shí)減少內(nèi)存(RAM)消耗的高效方法的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我必須將7個(gè)列表寫入XML文件,每個(gè)列表的大小為1 GB到5 GB。
預(yù)期輸出的XML文件如下:
<doc>
<items1>
<itemA>..</itemA>
..
</items1>
<items2>
<itemB>..</itemB>
..
</items2>
<items3>
<itemC>..</itemC>
..
</items3>
.
.
.
<items7>
<itemG>..</itemG>
..
</items7>
</doc>
Java對象如下:
List<ItemA> items1 = new List<>(); // 1GB-5GB
List<ItemB> items2 = new List<>(); // 1GB-5GB
List<ItemC> items3 = new List<>(); // 1GB-5GB
List<ItemD> items4 = new List<>(); // 1GB-5GB
List<ItemE> items5 = new List<>(); // 1GB-5GB
List<ItemF> items6 = new List<>(); // 1GB-5GB
List<ItemG> items7 = new List<>(); // 1GB-5GB
將所有列表包裝到單個(gè)對象(目錄)中到一個(gè)Java對象中,并且一次封送消耗大量內(nèi)存,而且每次當(dāng)列表大小增加時(shí),我們都必須縮放我們的底層。代碼如下:
JAXBContext.newInstance("ta").createMarshaller().marshal(new ObjectFactory().createCatalogue(catalogue), new FileOutputStream(fileName));
此處的Catalogue是一個(gè)包含所有七個(gè)列表的Java對象。
有沒有什么聰明的方法可以通過以塊為單位寫入數(shù)據(jù)來減少內(nèi)存消耗。為此,我研究了stax,但找不到寫入數(shù)據(jù)列表的方法。
在Java中,有沒有什么方法可以高效地將高達(dá)20 GB的數(shù)據(jù)寫入到XML中,而無需在基礎(chǔ)設(shè)施上擴(kuò)展RAM?
我們希望分別寫入每個(gè)列表,并且在寫入下一個(gè)列表時(shí)不應(yīng)將以前寫入的文件加載到堆中。
XMLX
使用StAX很可能是最好的方法,不僅因?yàn)槟槐貙⒄麄€(gè)推薦答案文檔保存在內(nèi)存中,而且還因?yàn)槟膊槐貙⑺?em>項(xiàng)都保存在內(nèi)存中。不知道您在哪里尋找StAX的寫作,但我在The Java EE 5 Tutorial中找到了以下內(nèi)容:
下面的示例摘自StAX規(guī)范,說明如何
實(shí)例化輸出工廠、創(chuàng)建編寫器并編寫XML輸出:XMLOutputFactory output = XMLOutputFactory.newInstance(); XMLStreamWriter writer = output.createXMLStreamWriter( ... ); writer.writeStartDocument(); writer.setPrefix("c","http://c"); writer.setDefaultNamespace("http://c"); writer.writeStartElement("http://c","a"); writer.writeAttribute("b","blah"); writer.writeNamespace("c","http://c"); writer.writeDefaultNamespace("http://c"); writer.setPrefix("d","http://c"); writer.writeEmptyElement("http://c","d"); writer.writeAttribute("http://c","chris","fry"); writer.writeNamespace("d","http://c"); writer.writeCharacters("Jean Arp"); writer.writeEndElement(); writer.flush();
此代碼生成以下XML(換行不規(guī)范):
<?xml version=’1.0’ encoding=’utf-8’?> <a b="blah" xmlns:c="http://c" xmlns="http://c"> <d:d d:chris="fry" xmlns:d="http://c"/> Jean Arp </a>
編輯:我還注意到有一個(gè)關(guān)于generating XML with StAX in the link you posted的部分。還要注意,編寫列表并沒有什么特別之處,您只需迭代列表并為每個(gè)條目編寫一個(gè)標(biāo)記即可。大概是這樣的:
XMLStreamWriter writer = ...;
writer.writeStartDocument();
writer.writeStartElement("doc");
// Write the first list:
writer.writeStartElement("items1");
for (ItemA e: items1) {
writer.writeStartElement("itemA");
// TODO: Write attributes, sub-elements, text or whatever is needed
writer.writeEndElement();
});
writer.writeEndElement();
// TODO: Write items2, items3, ..., items7 in the same fashion as items1
// Close document
writer.writeEndElement();
writer.writeEndDocument();
XMLStreamWriter是低級的,這意味著除了將XML寫入流之外,它不會為您做更多事情,但它并不復(fù)雜。因此,與使用JAXB相比,您最終可能需要更多的代碼行,但是您必須編寫的代碼不會特別難寫。
這篇關(guān)于在將大量文件數(shù)據(jù)寫入XML時(shí)減少內(nèi)存(RAM)消耗的高效方法的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,