Geração de arquivo CSV usando Java

8

Temos um requisito em nosso projeto para gerar um grande arquivo CSV a cada 2 horas usando um programa Java.

Este arquivo terá cerca de 60.000 linhas (cerca de 120 caracteres por linha). Ainda não tenho certeza do tamanho.

Gostaria de saber se me deparo com algum problema de memória, porque vou abrir o arquivo usando o FileWriter e continuar gravando e, finalmente, fechando o arquivo.

Devo me preocupar com o tamanho do arquivo? Se sim, existem outras boas técnicas para gravar em um arquivo grande em Java que não seja o FileWriter?

Estamos usando o Java 5.

java_mouse
fonte
Qual versão do Java você está usando?
Martijn Verburg
Yo ... quero dizer Nes. Droga, deixe-me pegar minha bola mágica 8.
Arrancado
Se a velocidade importa, tente um buffer realmente grande (de vários megabytes). Ele acelerou meu arquivo escrito por um fator de 10. Claro, os resultados podem variar ....
RalphChapin

Respostas:

14

Não, você não deveria. O objetivo de um arquivo é armazenar coisas fora da memória de acesso aleatório; o tamanho do FileWriter é constante e provavelmente muito pequeno, considerando tudo, mesmo que seja um FileWriter em buffer. A reescrita constante pode causar carga de E / S ou picos de CPU, mas quase certamente não falta de memória.

Kilian Foth
fonte
Eu pensei que os dados do arquivo serão mantidos na memória até eu fechar a máquina de escrever? parece que minha suposição está errada.
java_mouse
8
Não, um BufferedFileWriter manterá uma certa quantidade de dados na memória, mas essa quantidade é uma quantidade fixa, dependendo do ambiente em que é chamada. Não cresce sem limites com o número de bytes que você envia por ele - isso receita para o desastre!
Kilian Foth
8

Como Killian Foth escreveu, você não deve ter nenhum problema: 60000 linhas não são tão grandes assim. Eu só queria sugerir que você use qualquer um dos analisadores de CSV gratuitos fornecidos aqui sob a iniciativa "Commons CSV" em http://commons.apache.org/csv/ em vez de escrever sua própria implementação.

Eu usei o Super CSV em alguns projetos e certamente não tive nenhum problema com isso.

Jalayn
fonte
1
Eu usei o openCSV. Eu gosto disso. Linhas de 60K não é nada. Meu laptop antigo processa isso em um segundo.
ahoffer
Ótimo ouvir Jalayn! Acabamos de lançar uma nova versão do Super CSV com montes de correções de bugs, novos recursos e um novo site. Oh, e é agora, em Maven :) Central
James Bassett
5

Não use FileWriter. Não por questões de desempenho (as classes de E / S do Java não mantêm tudo na memória, as linhas de 60k não são nada, mesmo que o fizessem), mas porque não permite que você escolha a codificação de caracteres. Ele implicitamente usará a codificação padrão da plataforma, o que significa que o texto fora do ASCII pode ser corrompido.

Em vez disso, use um OutputStreamWriter envolvendo um FileOutputStream. Ou, melhor ainda, uma biblioteca CSV, que deve lidar com todos esses problemas.

Michael Borgwardt
fonte
Ou, em vez de OutputStreamWriter, use as classes NIO (FileChannel com ByteBuffers)? Todas as bibliotecas CSV lidam com codificação? Dei uma rápida olhada no SuperCSV e não vi nada sobre como lidar com a codificação.
Sam Goldberg
1
@ Sam Goldberg: você está certo, parece operar no Reader / Writer e deixar essa preocupação para o chamador.
Michael Borgwardt
@MichaelBorgwardt Você está certo - o Super CSV foi escrito usando IoC, então cabe a você fornecer um leitor / gravador - dessa forma, você pode gravar em um arquivo, arquivo zip, resposta HTTP, etc. Acabamos de lançar um novo versão - confira :) Ah, e quanto à codificação de caracteres, sempre achei o artigo de Joel Spolsky sobre Unicode excelente.
James Bassett
1

Você pode considerar usar o BufferedWriter, embora isso provavelmente não ajude significativamente com o desempenho, é uma prática recomendada em qualquer caso, pois imagino que o número de linhas nem sempre será 60.000.

Você pensou em fechar o arquivo depois? Se você pretende ter muitos desses arquivos disponíveis, pode ser do seu interesse compactá-lo após a gravação, especialmente se você estiver criando esses arquivos uma vez a cada duas horas.

No que diz respeito à memória, você provavelmente não terá nada com que se preocupar, a menos que esteja trabalhando em um sistema com muito pouca memória; nesse caso, você deve usar o BufferedWriter e definir explicitamente o tamanho do buffer.

Neil
fonte
1
O que é um BufferedFileWriter?
Michael Borgwardt
Opa Eu quis dizer BufferedWriter. Fixo.
840 Neil