Manipulacao de XML com JAXB extremamente lenta

Ola,
Eu fiz um codigo bem simples. Um esboço do que eu quero fazer. Porem está extremamente lento. Eu quero abrir um arquivo XML de uma nota fiscal eletronica (NFC-e), e pegar o falor do pagamento. O processo esta funcionando. Porem eu quero fazer isso usando todas as notas emitidas num mes. Estou fazendo um teste com 2200 arquivos. Esta levando mais de meia hora para concluir. O codigo é bem simples, esta logo abaixo, alguem usa alguma outra biblioteca para fazer isso?

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
	File diretorio = selecionarArquivo(true);
	if (diretorio == null) {
		JOptionPane.showMessageDialog(this, "Arquivo nao selecionado ou nao encontrado.", "Erro ao selecionar arquivo", JOptionPane.ERROR_MESSAGE);
	} else {
		StringBuffer sb = new StringBuffer();
		File[] arquivos = diretorio.listFiles();
		for (File arquivo : arquivos) {
			if (!arquivo.getName().contains("caneve")) {
				try {
                    //daqui
					JAXBContext contexto = JAXBContext.newInstance("br.inf.portalfiscal.nfe");
					Unmarshaller leituraXML = contexto.createUnmarshaller();
					JAXBElement<TNfeProc> objetoXML = (JAXBElement<TNfeProc>) leituraXML.unmarshal(arquivo);
					TNfeProc nfe = objetoXML.getValue();
                    //ate aqui, leva de 2 a 3 segundos por arquivo é o gargalo.
					sb.append(nfe.getNFe().getInfNFe().getId().substring(3));
					sb.append("\tEMISSAO:\t");
					sb.append(LocalDate.parse(nfe.getNFe().getInfNFe().getIde().getDhEmi(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
					sb.append("\r\n");
					for (TNFe.InfNFe.Pag.DetPag pag : nfe.getNFe().getInfNFe().getPag().getDetPag()) {
						sb.append("PAGAMENDO:\t");
						sb.append(pag.getTPag());
						sb.append("\tVALOR:\t");
						sb.append(pag.getVPag());
						sb.append("\r\n");
					}					
				} catch (JAXBException ex) {
					ex.printStackTrace();
				} 
			}
		}
		System.out.println(sb);
	}
}

Será que vc não pode reutilizar essas duas linhas? Talvez o contexto e o unmarshaller possa ser o mesmo para todos os arquivos. (obs.: Nunca precisei usar o jaxb, pensei nisso por dedução mesmo, talvez nem funcione)

1 curtida

JAXBContext contexto = JAXBContext.newInstance(“br.inf.portalfiscal.nfe”);

vc ta criando uma instancia de um pacote de classes a cada iteração do loop de arquivo. Tente passar apenas a classe desse Jaxb. a dica que o @ lucastody tbm não é desperdiçada…

1 curtida

eu ia excluir o topico, mas pode ser que sirva para outra pessoa.

   JAXBContext contexto = JAXBContext.newInstance("br.inf.portalfiscal.nfe");

essa criacao de uma instancoa do JAXBContext deve ser invocada uma unica vez e caso necessario voce compartilha ela entre os objetos. O meu erro foi ficar criando varias vezes dentro do for.
Nesse caso bastou retirar do for sua criacao, juntamente com a do Unmarshaller. Que agora nao leva mais nem 1 segundo a mesma tarefa.

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
	File diretorio = selecionarArquivoDaColeta(true);
	if (diretorio == null) {
		JOptionPane.showMessageDialog(this, "Arquivo nao selecionado ou nao encontrado.", "Erro ao selecionar arquivo", JOptionPane.ERROR_MESSAGE);
	} else {
		long t1 = System.currentTimeMillis();
		StringBuffer sb = new StringBuffer();
		File[] arquivos = diretorio.listFiles();
		try {
			//Retirei a criacao desses dois objetos do for. 
			JAXBContext contexto = JAXBContext.newInstance("br.inf.portalfiscal.nfe");
			Unmarshaller leituraXML = contexto.createUnmarshaller();
			for (File arquivo : arquivos) {
				if (!arquivo.getName().contains("caneve")) {
					JAXBElement<TNfeProc> objetoXML = (JAXBElement<TNfeProc>) leituraXML.unmarshal(arquivo);
					TNfeProc nfe = objetoXML.getValue();
					sb.append(nfe.getNFe().getInfNFe().getId().substring(3));
					sb.append("\tEMISSAO:\t");
					sb.append(LocalDate.parse(nfe.getNFe().getInfNFe().getIde().getDhEmi(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
					sb.append("\r\n");
					for (TNFe.InfNFe.Pag.DetPag pag : nfe.getNFe().getInfNFe().getPag().getDetPag()) {
						sb.append("PAGAMENDO:\t");
						sb.append(pag.getTPag());
						sb.append("\tVALOR:\t");
						sb.append(pag.getVPag());
						sb.append("\r\n");
					}
				}
			}
		} catch (JAXBException ex) {
			ex.printStackTrace();
		}
		System.out.println(sb);
	}
}      
1 curtida

blz, eu fui dar uma googada, e achei essa sua dica. valeu ae.

valeu obrigado, foi justamente isso

1 curtida