4
我正在使用VTD-XML解析許多XML文件。我不確定我是否正確使用了該工具 - 我認爲是這樣,但解析這些文件讓我過了很久。使用VTD-XML優化解析XML文件的速度
xml文件(DATEXII格式)是HD上的壓縮文件。解壓縮它們大約31MB,包含超過850.000行文本。我只需要提取幾個字段並將它們存儲在數據庫中。
import org.apache.commons.lang3.math.NumberUtils;
...
private static void test(File zipFile) throws XPathEvalException, NavException, XPathParseException {
// init timer
long step1=System.currentTimeMillis();
// open file to output extracted fragments
VTDGen vg = new VTDGen();
vg.parseZIPFile(zipFile.getAbsolutePath(), zipFile.getName().replace(".zip",".xml"),true);
VTDNav vn = vg.getNav();
AutoPilot apSites = new AutoPilot();
apSites.declareXPathNameSpace("ns1", "http://schemas.xmlsoap.org/soap/envelope/");
apSites.selectXPath("/ns1:Envelope/ns1:Body/d2LogicalModel/payloadPublication/siteMeasurements");
apSites.bind(vn);
long step2=System.currentTimeMillis();
System.out.println("Prep took "+(step2-step1)+"ms; ");
// init variables
String siteID, timeStr;
boolean reliable;
int index, flow, ctr=0;
short speed;
while(apSites.evalXPath()!=-1) {
vn.toElement(VTDNav.FIRST_CHILD, "measurementSiteReference");
siteID = vn.toString(vn.getText());
// loop all measured values of this measurement site
while(vn.toElement(VTDNav.NEXT_SIBLING, "measuredValue")) {
ctr++;
// extract index attribute
index = NumberUtils.toInt(vn.toString(vn.getAttrVal("index")));
// go one level deeper into basicDataValue
vn.toElement(VTDNav.FIRST_CHILD, "basicDataValue");
// we need either FIRST_CHILD or NEXT_SIBLING depending on whether we find something
int next = VTDNav.FIRST_CHILD;
if(vn.toElement(next, "time")) {
timeStr = vn.toString(vn.getText());
next = VTDNav.NEXT_SIBLING;
}
if(vn.toElement(next, "averageVehicleSpeed")) {
speed = NumberUtils.toShort(vn.toString(vn.getText()));
next = VTDNav.NEXT_SIBLING;
}
if(vn.toElement(next, "vehicleFlow")) {
flow = NumberUtils.toInt(vn.toString(vn.getText()));
next = VTDNav.NEXT_SIBLING;
}
if(vn.toElement(next, "fault")) {
reliable = vn.toString(vn.getText()).equals("0");
}
// insert into database here...
if(next==VTDNav.NEXT_SIBLING) {
vn.toElement(VTDNav.PARENT);
}
vn.toElement(VTDNav.PARENT);
}
}
System.out.println("Loop took "+(System.currentTimeMillis()-step2)+"ms; ");
System.out.println("Total number of measured values: "+ctr);
}
我的XML的文件準確上述功能的輸出是:
Prep took 25756ms;
Loop took 26889ms;
Total number of measured values: 112611
沒有數據實際上是插入到數據庫中現在。現在問題是我每分鐘收到一個這樣的文件。現在總解析時間將近1分鐘,而且由於下載文件需要大約10秒鐘,而且我需要將數據存儲在數據庫中,所以我現在正在實時運行。
有什麼辦法可以加快速度嗎?事情我已經試過了沒有幫助:
- 所有字段使用自動駕駛儀,這實際上是由第二步速度慢一些30000ms
- 解壓文件自己並解析字節數組VTD,這次沒任何區別
- 循環使用自己一個BufferedReader的readLine()的文件,但這是不夠快或者
是否有人看到一種可能性,加快速度,或者我需要開始思考一個更重的機器/多線程?當然,每分鐘850.000行(每天12億行)是很多,但我仍然認爲它不應該花一分鐘來解析31MB的數據...
你可以將問題發佈到vtd-xml郵件列表,我很樂意幫你解決問題。 – 2012-07-15 05:28:07