Ordenar Colunas de um arquivo Csv

Olá.

Estou com um problema de lógica aqui.
Tenho um arquivo separado por colunas, como esse:

nome;usuario;senha usuario1;ebanton;123456 usuario2;mbanton;qaywsx usuario3;mmeincke;qwertz usuario4;hworm;qweasd usuario5;nklein;asdyxc usuario6;jberni;123qwe usuario7;afriedrich;qwe123

Ele é um arquivo CSV. Preciso organizar as colunas de outra maneira, por exemplo usuario;nome;senha.

Como posso fazer isso? Nao estou com idéia de como posso fazer isso.

Valeu.

Primeiro vais ter de ler o arquivo. Podes carregá-lo em um StringTokenizer pelo ponto e vírgula. Depois é só reescrevê-lo no arquivo novamente:

//...
BufferedReader reader = new BufferedReader(new FileReader("damnit.csv"));

StringTokenizer token;
String aLine;
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    //agora pega o conteúdo e manipula como quiser,
    //armazena e regrava no arquivo...
}
//...

T+

[quote=“iktuz”]Primeiro vais ter de ler o arquivo. Podes carregá-lo em um StringTokenizer pelo ponto e vírgula. Depois é só reescrevê-lo no arquivo novamente:

//...
BufferedReader reader = new BufferedReader(new FileReader("damnit.csv"));

StringTokenizer token;
String aLine;
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    //agora pega o conteúdo e manipula como quiser,
    //armazena e regrava no arquivo...
}
//...

T+[/quote]

Valeu pela dica. Essa parte era o que eu tinha imaginado.
Já havia até testado carregar o arquivo pelo StringTokenizer e separando pelo ponto e vírgula.

Eu nao tenho idéia de como posso fazer para alterar a ordem das colunas.
Você poderia me dar uma ajuda??

Valeu.

Primeiro deves ter certeza de que o número de colunas seja realmente o que é esperado. No teu caso são 3 colunas. Então reconcatena os valores na ordem desejada e vai armazenando para finalmente regravar o arquivo:

public static final int EXPECTED = 3;
public static final char SEP = ';';
public static final char ENTER = '\n';

//...
String first, second, third, newOrder, newBuffer;
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    if (token.countTokens() != EXPECTED) {
        throw new Exception("Illegal column count: "+token.countTokens());
    }
    first = token.nextToken();
    second = token.nextToken();
    third = token.nextToken();
    newOrder = third + SEP + first + SEP + second;
    newBuffer = newOrder + ENTER;
}
//...

Depois disso cria um writer e escreve o que estiver dentro de newBuffer. É isto. T+

[quote=“iktuz”]Primeiro deves ter certeza de que o número de colunas seja realmente o que é esperado. No teu caso são 3 colunas. Então reconcatena os valores na ordem desejada e vai armazenando para finalmente regravar o arquivo:

public static final int EXPECTED = 3;
public static final char SEP = ';';
public static final char ENTER = '\n';

//...
String first, second, third, newOrder, newBuffer;
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    if (token.countTokens() != EXPECTED) {
        throw new Exception("Illegal column count: "+token.countTokens());
    }
    first = token.nextToken();
    second = token.nextToken();
    third = token.nextToken();
    newOrder = third + SEP + first + SEP + second;
    newBuffer = newOrder + ENTER;
}
//...

Depois disso cria um writer e escreve o que estiver dentro de newBuffer. É isto. T+[/quote]

iktuz

Muito obrigado. Ainda nao implementei o que voce falou acima, mas tenho outra coisa a acrescentar.
O número de colunas vai ser variável. Mas acho que isso nao é um grande problema. Basta eu ler uma linha do arquivo e separar as colunas e armazenar o número em EXPECTED correto?
Este trecho de código que voce passou é para fazer o que exatamente?

Obrigao.

Se o número de colunas vai ser variável, vais ter de tomar cuidado ao tentar trocar as “colunas” que eventualmente não existem. Eu coloquei a constante EXPECTED pra garantir de que eu vou conseguir ler 3 tokens. Se tu não usar isto, e tentar ler um token que não está lá, vai tomar exceção. Este código é para trocar a ordem da colunas. Faz um programinha simples e roda ele com vários “sysout” e vai acompanhando. T+

Ok, vou testar.

Só nao entendi o que “sysout” para voce?? Desculpe mas é que eu sou bem iniciante mesmo…eehe

Que IDE estais usando? Se estiver com o Eclipse 3.x, digita no corpo da tua classe “sysout” e pressiona CTRL + SPACE BAR com o cursor logo depois dele. Ele gera um System.out.println(); pra ti.

Mas o atalho mais “matador” é o CTRL + SHIF + L, pois lista todos os demais atalhos.

T+

Legal. Estou usando o Eclipse 3.x sim.
Nao sabia desses atalhos. Sabia que ao estar digitando um comando pode se teclar CTRL + SPACE BAR para ver uma lista dos comandos disponíveis.

Bom, vou ao trabalho testar essa sua dica.

Valeu

Consegui entender o seu código.

O problema é que se eu tiver um número N de colunas, como vou criar aquelas variáveis first, second, etc ?
Acho que nao tem como armazenar em Strings comuns daí, ou tem?

Sem saber quantos colunas tu vais ter vai ficar mais difícil de trocar uma posição pela outra, principalmente se for entre uma que está no arquivo e outra que não. De qualquer forma pra que queres inverter posições das colunas? Se estais carregando estes dados para mostrar em um JTable por exemplo, podes fazer isto no modelo de dados. Se ainda assim tu quer mudar as posições das colunas primeiro vais ter de verificar quais estão lá para então depois trocar. T+

Seguinte. Não sei se realmente eu preciso inverter as colunas.
O caso é que eu terei um arquivo CSV com um número N de colunas e terei que iserir os dados num Banco de Dados.
Acontece que nem sempre as colunas do arquivo CSV estarão na mesma ordem que no BD. Se fosse sempre iguais bastaria eu ler o arquivo e inserir no BD.
Para saber qual coluna do arquivo CSV vai em qual coluna do BD eu terei um arquivo .properties com as informações. Por exemplo:

nome1_coluna_csv = nome1_coluna_BD
nome2_coluna_csv = nome2_coluna_BD
nome3_coluna_csv = nome3_coluna_BD

Esse arquivo eu vou ter pronto. Então preciso comparar as colunas do CSV com esse arquivo properties e inserir de forma correta no BD. Ai não sei se realmente tenho que alterar a ordem das colunas do arquivo CSV ou se existe uma maneira de eu inserir no BD diretamente.
Conseguistes entender?

Se puder me ajudar.

Obrigado.

A primeira linha do CSV vem com o nome das colunas, assim sabes a que atributo cada valor se trata. Depois preencha um bean com os dados e mande persistir.

Então tens o bean:

public class Pessoa {
    private String nome;
    private String email;
    private String sobreNome;
    //getters & setters...
}

O leitor dos dados:

public List loadPessoas() {
List pessoas = new ArrayList();
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    if (token.countTokens() != EXPECTED) {
        throw new Exception("Illegal column count: "+token.countTokens());
    }
    Pessoa p = new Pessoa();
    p.setNome(token.nextToken());
    p.setEmail(token.nextToken());
    p.setSobreNome(token.nextToken());
    pessoas.add(p);
return pessoas;
}

Com a lista de pessoas carregadas constrói um Broker para persistir os dados no banco:

public class PessoaBroker {
    public void savePessoas(List pessoas) {
        //TODO insert de tudo...
    }
}

Pra usar:

//...
List pessoas = loadPessoas();
new PessoaBroker().savePessoas(pessoas);
//...

É isto, T+

[quote=“iktuz”]A primeira linha do CSV vem com o nome das colunas, assim sabes a que atributo cada valor se trata. Depois preencha um bean com os dados e mande persistir.

Então tens o bean:

public class Pessoa {
    private String nome;
    private String email;
    private String sobreNome;
    //getters & setters...
}

O leitor dos dados:

public List loadPessoas() {
List pessoas = new ArrayList();
while ((aLine = reader.readLine) != null) {
    token = new StringTokenizer(aLine, ";");
    if (token.countTokens() != EXPECTED) {
        throw new Exception("Illegal column count: "+token.countTokens());
    }
    Pessoa p = new Pessoa();
    p.setNome(token.nextToken());
    p.setEmail(token.nextToken());
    p.setSobreNome(token.nextToken());
    pessoas.add(p);
return pessoas;
}

Com a lista de pessoas carregadas constrói um Broker para persistir os dados no banco:

public class PessoaBroker {
    public void savePessoas(List pessoas) {
        //TODO insert de tudo...
    }
}

Pra usar:

//...
List pessoas = loadPessoas();
new PessoaBroker().savePessoas(pessoas);
//...

É isto, T+[/quote]

Olá…desculpe mas eu nao entendi tudo…
O que seria um bean?
E porque essa classe Pessoa? É que no meu arquivo CSV nem sempre serão os mesmos nomes de colunas.

Valeu.

Bean é um componente que representa e encapsula as informações que queres armazenar. É simplesmente um mapeamento entre a tua informação e um objeto Java na tua aplicação. Quando os campos não existirem o bean terá o campo vazio (null). T+

Ok.

Eu só não entendi poque você criou a classe Pessoa.
No meu arquivo CSV nem sempre irá conter dados relativos a uma pessoa. Pode ser qualquer dado. Aí que eu tenho a dúvida, eu não sei como posso fazer isso.

Se você tiver alguma idéia e puder me ajudar eu agradeço…

Obrigado.