Manipulacao de XML com JAXB extremamente lenta

5 respostas Resolvido
xmlprogramaçãojava
thimor

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);
	}
}

5 Respostas

Lucas_Camara
Solucao aceita

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)

B

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…

thimor

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);
	}
}
thimor

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

thimor

valeu obrigado, foi justamente isso

Criado 28 de abril de 2020
Ultima resposta 28 de abr. de 2020
Respostas 5
Participantes 3