Senhores(as), preciso de uma ajuda para compreender o que está ocorrendo para a seguintes linhas contida num .txt. Eu lerei essas informações e as inserirei em um banco de dados. Cada coluna é separada por “;” e mesmo as que não tem informação devem ser populadas no bean. O problema ocorre quando tenho uma coluna vazia, apenas com o valor “;” …o token não conta tal coluna, abaixo tenho 14 colunas, mas ao rodar só reconhece 7 tokens…
ARQUIVO TXT
903;DÉBITOS;0000000000;;;; ;;;;;-30;-30;SALDO DEVEDOR REF. LOTE Nº 10;
903;DÉBITOS;20623;;08/01/2009;1; ;;;;;-10;-10;Tx. Adesão,AMIL SAÚDE,RENATA ALMEIDA ;
ROTINA LEITURA
private void processFile(HttpServletRequest request) throws BDOException {
try {
String transacao = getBufferFile().readLine();
while (transacao != null) {
StringTokenizer colunas = new StringTokenizer(transacao, ";");
while (colunas.hasMoreTokens()) {
int idVendedor = Integer.parseInt(colunas.nextToken().trim());
String operadora = colunas.nextToken().trim();
String numeroProposta = colunas.nextToken().trim();
String cliente = colunas.nextToken().trim();
String idLote = colunas.nextToken().trim();
String dataAdesao = colunas.nextToken().trim();
String parcela = colunas.nextToken().trim();
String dataPagto = colunas.nextToken().trim();
String valorPago = colunas.nextToken().trim();
String porcComissao = colunas.nextToken().trim();
String valorComissao = colunas.nextToken().trim();
String porcDesconto = colunas.nextToken().trim();
String valorDesconto = colunas.nextToken().trim();
String valorLiquido = colunas.nextToken().trim();
ProcessImport dto = new ProcessImport();
dto.setIdVendedor(idVendedor);
dto.setIdLote(idLote);
dto.setOperadora(operadora);
dto.setCliente(cliente);
dto.setNumeroProposta(numeroProposta);
dto.setCliente(cliente);
dto.setDataAdesao(dataAdesao);
dto.setParcela(parcela);
dto.setDataPagto(dataPagto);
dto.setValorPago(valorPago);
dto.setPorcComissao(porcComissao);
dto.setValorComissao(valorComissao);
dto.setPorcDesconto(porcDesconto);
dto.setValorDesconto(valorDesconto);
dto.setValorLiquido(valorLiquido);
FactoryDAO.getProcessImport(request).insert(dto);
transacao = bufferFile.readLine();
dto = null;
}
}
} catch (IOException e) {
throw new BDOException("Erro ao processar o arquivo.");
} catch (DAOException e) {
throw new BDOException("Erro ao inserir os registros.");
}
}
Uma alternativa seria trocar os caracteres ;; por ; ;
Seria assim:
String transacao = "903;DÉBITOS;20623;;08/01/2009;1; ;;;;;-10;-10;Tx. Adesão,AMIL SAÚDE,RENATA ALMEIDA ; ";
transacao =transacao.replace(";;", "; ;");
System.out.println(transacao);
StringTokenizer colunas = new StringTokenizer(transacao, ";");
System.out.println(colunas.countTokens());
while (colunas.hasMoreTokens()) {
System.out.println(colunas.nextToken().trim());
}
Bom meneghette !!
Então, ja testei dessa forma, e não funciona.
Alguma :idea:.
Obrigado!
robinson,
Testei da forma que te passei e deu certo… veja o resultado:
Qtde Colunas = 13
903
DÉBITOS
20623
08/01/2009
1
-10
-10
Tx. Adesão,AMIL SAÚDE,RENATA ALMEIDA
Estranho é que ele está ignorando uma coluna ainda.
O seguinte layout foi utilizado para o arquivo:
Coluna 1 - Cód. Vendedor
Coluna 2 - Operadora
Coluna 3 - Nro. Proposta
Coluna 4 - Cliente
Coluna 5 - Lote
Coluna 6 - Data Adesão
Coluna 7 - Parcela
Coluna 8 - Data Pagto
Coluna 9 - Valor Pago
Coluna 10 - % Comissão
Coluna 11 - Valor Comisão
Coluna 12 - % Desconto
Coluna 13 - Valor Desconto
Coluna 14 - Valor Líquido
É verdade, você tem razão, pois quando fez o repalce… restaram alguns ;; juntos, assim ele não encontrou todas as colunas…
fiz a seguinte alteração e agora deu:
[code]public static void main(String[] args) {
String transacao = "903;DÉBITOS;20623;;08/01/2009;1; ;;;;;-10;-10;Tx. Adesão,AMIL SAÚDE,RENATA ALMEIDA ; ";
while (transacao.contains(";;"))
transacao =transacao.replace(";;", “; ;”);
System.out.println(transacao);
StringTokenizer colunas = new StringTokenizer(transacao, ";");
System.out.println(colunas.countTokens());
while (colunas.hasMoreTokens()) {
System.out.println(colunas.nextToken().trim());
}
}[/code]
Consegui resolver esse problema sem ter que recorrer a “gambiarras.rs” 8)
Veja a solução abaixo:
String linha = "903;DÉBITOS;0000000000;;;; ;;;;;-30;-30;SALDO DEVEDOR REF. LOTE Nº 10;"; //teste
String colunas[] = linha.split("\;");
for(String coluna : colunas){
System.out.println(coluna);
}
VALEU PELA FORÇA meneghette !!!
robinson silva,
Quando for tokenizar alguma coisa, use a classe Scanner. Acredito que ela seja o Cadilac da tokenizacao.
Abracos.
<><
thingol
Fevereiro 11, 2009, 8:51am
#10
[quote=robinsonbsilva]Senhores(as), preciso de uma ajuda para compreender o que está ocorrendo para a seguintes linhas contida num .txt. Eu lerei essas informações e as inserirei em um banco de dados. Cada coluna é separada por “;” e mesmo as que não tem informação devem ser populadas no bean. O problema ocorre quando tenho uma coluna vazia, apenas com o valor “;” …o token não conta tal coluna, abaixo tenho 14 colunas, mas ao rodar só reconhece 7 tokens…
ARQUIVO TXT
903;DÉBITOS;0000000000;;;; ;;;;;-30;-30;SALDO DEVEDOR REF. LOTE Nº 10;
903;DÉBITOS;20623;;08/01/2009;1; ;;;;;-10;-10;Tx. Adesão,AMIL SAÚDE,RENATA ALMEIDA ;
ROTINA LEITURA
[code]
private void processFile(HttpServletRequest request) throws BDOException {
try {
String transacao = getBufferFile().readLine();
while (transacao != null) {
StringTokenizer colunas = new StringTokenizer(transacao, ";");
while (colunas.hasMoreTokens()) {
int idVendedor = Integer.parseInt(colunas.nextToken().trim());
String operadora = colunas.nextToken().trim();
String numeroProposta = colunas.nextToken().trim();
String cliente = colunas.nextToken().trim();
String idLote = colunas.nextToken().trim();
String dataAdesao = colunas.nextToken().trim();
String parcela = colunas.nextToken().trim();
String dataPagto = colunas.nextToken().trim();
String valorPago = colunas.nextToken().trim();
String porcComissao = colunas.nextToken().trim();
String valorComissao = colunas.nextToken().trim();
String porcDesconto = colunas.nextToken().trim();
String valorDesconto = colunas.nextToken().trim();
String valorLiquido = colunas.nextToken().trim();
ProcessImport dto = new ProcessImport();
dto.setIdVendedor(idVendedor);
dto.setIdLote(idLote);
dto.setOperadora(operadora);
dto.setCliente(cliente);
dto.setNumeroProposta(numeroProposta);
dto.setCliente(cliente);
dto.setDataAdesao(dataAdesao);
dto.setParcela(parcela);
dto.setDataPagto(dataPagto);
dto.setValorPago(valorPago);
dto.setPorcComissao(porcComissao);
dto.setValorComissao(valorComissao);
dto.setPorcDesconto(porcDesconto);
dto.setValorDesconto(valorDesconto);
dto.setValorLiquido(valorLiquido);
FactoryDAO.getProcessImport(request).insert(dto);
transacao = bufferFile.readLine();
dto = null;
}
}
} catch (IOException e) {
throw new BDOException("Erro ao processar o arquivo.");
} catch (DAOException e) {
throw new BDOException("Erro ao inserir os registros.");
}
}
[/code][/quote]
Não use StringTokenizer de forma alguma para separar campos se houver campos vazios.
Não use, não use e não use; ponto final.
Olhe o fonte de StringTokenizer se tiver alguma dúvida.
Se precisar separar campos vazios, use String.split, que é o que você deveria ter usado desde o começo.
E mais uma coisa: use a versão com 2 parâmetros de String.split. É que a versão com 1 parâmetro não retorna os campos vazios no final da string; a com 2 parâmetros (sendo o 2o. parâmetro = -1) consegue retornar os campos vazios.
Valeu thingol pelos esclarecimentos!!!
Como funcionaria esse:
public String[] split(String regex,int limit)
Pois eu usei a versão com um parâmetro
String linha = "903;DÉBITOS;0000000000;;;; ;;;;;-30;-30;SALDO DEVEDOR REF. LOTE Nº 10;"; //teste
String colunas[] = linha.split("\;");
for(String coluna : colunas){
System.out.println(coluna);
}
thingol
Fevereiro 11, 2009, 9:32am
#12
limit (o segundo parâmetro) indica qual é o tamanho máximo do array que String.split deve retornar, se for positivo. Por exemplo,
String s = "a;b;c;d;e;f;g;h;;;";
String[] t = s.split (";", 5);
iria retornar um array t de 5 elementos com o conteúdo “a”, “b”, “c”, “d”, “e;f;g;h;;;”.
Se você passar -1, então ele não tem limite nenhum, e também volta os campos vazios no final da string caso existirem. Por exemplo,
String s = "a;b;c;d;e;f;g;h;;;";
String[] t = s.split (";", -1);
iria retornar um array t com o conteúdo “a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “”, “”, “”. (Tomei pau em contabilidade e não sei contar ou fazer contas, por favor conte quantos elementos teria o array.)
ozix
Fevereiro 11, 2009, 10:57am
#14
robinson, repare no código do thingol que a barra dupla que você colocou como argumento para o split é desnecessária.
flw.