Generación de archivos CSV utilizando Java

8

Tenemos un requisito en nuestro proyecto para generar un gran archivo CSV cada 2 horas utilizando un programa Java.

Este archivo tendrá alrededor de 60,000 líneas (alrededor de 120 caracteres por línea). Todavía no estoy seguro del tamaño.

Me gustaría saber si me encontraría con algún problema de memoria porque abriré el archivo usando FileWriter y luego seguiré escribiendo y finalmente cerraré el archivo.

¿Debería preocuparme por el tamaño del archivo? En caso afirmativo, ¿hay otras buenas técnicas para escribir en un archivo grande en Java que no sea el uso de FileWriter?

Estamos usando Java 5.

java_mouse
fuente
¿Qué versión de Java estás usando?
Martijn Verburg
Yo ... me refiero a Nes. Maldición, déjame obtener mi bola mágica 8.
Estafado
Si la velocidad es importante, pruebe un búfer realmente grande (multi-megabyte). Se aceleró mi escritura de archivos en un factor de 10. Por supuesto, sus resultados pueden variar ....
RalphChapin

Respuestas:

14

No, no deberías El objetivo de un archivo es almacenar cosas fuera de la memoria de acceso aleatorio; el tamaño de FileWriter es constante, y es probable que sea bastante pequeño, considerando todo, incluso si se trata de un FileWriter almacenado en búfer. La reescritura constante puede causar una carga de E / S o picos de CPU, pero casi seguro que no hay escasez de memoria.

Kilian Foth
fuente
¿Pensé que los datos del archivo se guardarán en la memoria hasta que cierre el escritor de archivos? Parece que mi suposición es incorrecta.
java_mouse
8
No, un BufferedFileWriter mantendrá una cierta cantidad de datos en la memoria, pero esa cantidad es una cantidad fija, dependiendo del entorno en el que se llame. No crece sin límites con la cantidad de bytes que ingresas, eso sería un receta para el desastre!
Kilian Foth
8

Como Killian Foth lo escribió, no debería tener ningún problema, 60000 líneas no es tan grande. Solo quería sugerirle que use cualquiera de los analizadores de CSV gratuitos proporcionados aquí bajo la iniciativa "Commons CSV" en http://commons.apache.org/csv/ en lugar de escribir su propia implementación.

He usado Super CSV para algunos proyectos y ciertamente no tuve ningún problema con él.

Jalayn
fuente
1
Usé openCSV. Me gusta. 60K líneas no es nada. Mi vieja computadora portátil procesa eso en un segundo.
ahoffer
¡Qué bueno escuchar a Jalayn! Acabamos de lanzar una nueva versión de Super CSV con un montón de correcciones de errores, nuevas funciones y un nuevo sitio web. Ah, y ahora está en Maven central :)
James Bassett
5

No use FileWriter. No por problemas de rendimiento (las clases IO de Java no guardan todo en la memoria, ut 60k líneas no son nada, incluso si lo hicieran), sino porque no le permite elegir la codificación de caracteres. Implícitamente usará la codificación predeterminada de la plataforma, lo que significa que el texto fuera de ASCII puede corromperse.

En su lugar, use un OutputStreamWriter envolviendo un FileOutputStream. O, mejor aún, una biblioteca CSV, que debería manejar todos estos problemas.

Michael Borgwardt
fuente
¿O en lugar de OutputStreamWriter, usa clases NIO (FileChannel con ByteBuffers)? ¿Todas las bibliotecas CSV manejan la codificación? Eché un vistazo rápido a SuperCSV y no vi nada sobre el manejo de la codificación.
Sam Goldberg,
1
@Sam Goldberg: tienes razón, parece funcionar en Reader / Writer y deja esa preocupación a la persona que llama.
Michael Borgwardt
@MichaelBorgwardt Tienes razón: Super CSV se escribió usando IoC, por lo que depende de ti proporcionar un lector / escritor, de esa manera puedes escribir en un archivo, archivo zip, respuesta HTTP, etc. Acabamos de lanzar un nuevo versión - por favor échale un vistazo :) Ah, y en cuanto a la codificación de caracteres, siempre he encontrado excelente el artículo de Joel Spolsky sobre Unicode .
James Bassett
1

Puede considerar usar BufferedWriter, aunque eso probablemente no ayudará significativamente con el rendimiento, es una práctica recomendada en cualquier caso, ya que imagino que el número de líneas no siempre será de 60,000.

¿Has considerado comprimir el archivo después? Si tiene la intención de tener muchos de estos archivos, podría ser mejor para usted comprimirlos después de haberlos escrito, especialmente si va a crear estos archivos una vez cada dos horas.

En lo que respecta a la memoria, probablemente no tenga nada de qué preocuparse a menos que esté trabajando en un sistema con muy poca memoria, en cuyo caso debe usar BufferedWriter y establecer explícitamente el tamaño del búfer.

Neil
fuente
1
¿Qué es un BufferedFileWriter?
Michael Borgwardt
Ups Me refería a BufferedWriter. Fijo.
Neil