gpt4 book ai didi

java - 如何使用 STAX api 处理大型 XML 文件 (9 GB)

转载 作者:行者123 更新时间:2023-11-30 03:11:35 27 4
gpt4 key购买 nike

在处理大文件时,我总是遇到堆内存问题。这里我正在处理 9 GB 的 xml 文件。

这是我的代码。

            XMLInputFactory inputFactory = XMLInputFactory.newInstance();
InputStream in = new FileInputStream(sourcePath);
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);

Map<String, Cmt> mapCmt = new ConcurrentHashMap<String, Cmt>();
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
//some processing and assigning value to map
Cmt cmt = new Cmt();
//get attributes
cmt.setDetails(attribute.getValue());
mapCmt.put(someKey,cmt);
}
}

一段时间后,我在迭代中遇到堆内存问题。请帮助我编写优化的代码。

注意:服务器有 3 GB 可用堆空间。我无法增加服务器空间。我正在使用以下参数执行 -Xms1024m -Xmx3g

我的 xml 看起来像这样。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DatosAbonados xmlns="http://www.cnmc.es/DatosAbonados">
<DatosAbonado Operacion="1" FechaExtraccion="2015-10-08">
<Titular>
<PersonaJuridica DocIdentificacionJuridica="A84619488" RazonSocial="HERMANOS ROJAS" NombreComercial="PINTURAS ROJAS"/>
</Titular>
<Domicilio Escalera=" " Piso=" " Puerta=" " TipoVia="AVENIDA" NombreVia="MANOTERAS" NumeroCalle="10" Portal=" " CodigoPostal="28050" Poblacion="Madrid" Provincia="28"/>
<NumeracionAbonado>
<Rangos NumeroDesde="211188600" NumeroHasta="211188699" ConsentimientoGuias-Consulta="1" VentaDirecta-Publicidad="1" ModoPago="1">
<Operador RazonSocial="11888 SERVICIO CONSULTA TELEFONICA S.A." DocIdentificacionJuridica="A83519389"/>
</Rangos>
</NumeracionAbonado>
</DatosAbonado>
<DatosAbonado Operacion="1" FechaExtraccion="2015-10-08">
<Titular>
<PersonaJuridica DocIdentificacionJuridica="A84619489" RazonSocial="HERMANOS RUBIO" NombreComercial="RUBIO PELUQUERIAS"/>
</Titular>
<Domicilio Escalera=" " Piso=" " Puerta=" " TipoVia="AVENIDA" NombreVia="BURGOS" NumeroCalle="18" Portal=" " CodigoPostal="28036" Poblacion="Madrid" Provincia="28"/>
<NumeracionAbonado>
<Rangos NumeroDesde="211186000" NumeroHasta="211186099" ConsentimientoGuias-Consulta="1" VentaDirecta-Publicidad="1" ModoPago="1">
<Operador RazonSocial="11888 SERVICIO CONSULTA TELEFONICA S.A." DocIdentificacionJuridica="A83519389"/>
</Rangos>
</NumeracionAbonado>
</DatosAbonado>
</DatosAbonados>

我的 Cmt 类(class)是:

public class Cmt {
private List<DetailInfo> details;

public List<DetailInfo> getDetails() {
return details;
}
public void setDetails(DetailInfo detail) {
if(details == null){
details = new ArrayList<DetailInfo>();
}
this.details.add(detail);
}
}

Actually Cmt object is very less, But i have DetailInfo object for every element. So huge no. of DetailInfo object is created.

我的逻辑是这样的:

if (startElement.getName().getLocalPart().equals("DatosAbonado")) {
detailInfo = new DetailInfo();

Iterator<Attribute> attributes = startElement.getAttributes();
while (attributes.hasNext()) {
Attribute attribute = attributes.next();
if(attribute.getName().toString().equals("Operacion")){
detailInfo.setOperacion(attribute.getValue());
}
}
}
if (event.isEndElement()) {
EndElement endElement = event.asEndElement();
if (endElement.getName().getLocalPart().equals("DatosAbonado")) {
Cmt cmt = null;
if(mapCmt.keySet().contains(identificador)){
cmt = mapCmt.get(identificador);
} else{
cmt = new Cmt();
}
cmt.setDetails(detailInfo);
mapCmt.put(identificador, cmt);
}
}

最佳答案

您的问题的根源很可能是这样的:

mapCmt.put(someKey, cmt);

您正在使用许多大型 Cmt 对象填充 HashMap 。您需要执行以下操作之一:

  • 立即处理数据,而不是将其保存在数据结构中。
  • 将数据写入数据库以供以后查询。
  • 增加堆大小。
  • 为您的数据找出一种“内存消耗较少”的表示方式。

最后两种方法无法扩展。随着输入文件大小的增加,您将需要逐渐更多的内存......直到最终超出执行平台的内存容量。

关于java - 如何使用 STAX api 处理大型 XML 文件 (9 GB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33518452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com