2010-12-17 13 views
5

Escenario:¿Está lanzando una operación costosa?

  • estoy analizar un (archivo de caracteres) del archivo grande. Por ejemplo, un archivo .csv (no es exactamente mi caso)
  • No puedo guardar todo el archivo en la memoria. Entonces debo implementar una estrategia de amortiguación.
  • Quiero construir un controlador genérico que mantenga un número constante de líneas en la memoria (como cadenas). Este manejador busca otras líneas si es necesario mientras elimina las líneas innecesarias.
  • Sobre este controlador construiré un analizador sintáctico que transformará las líneas en objetos Java y operará cambios en esos objetos. Una vez que se realizan los cambios (actualice algunos campos en los objetos) persista los cambios en el archivo.

¿Debo:

  • En lugar de mantener el búfer como una matriz de cadenas, debo mantener el buffer directamente como objetos (hacer un solo molde)? o ...
  • Mantenga el búfer como líneas, cada vez que necesite operar en el búfer, envíe la información al objeto correcto, realice los cambios, persista los cambios en el archivo. Las operaciones secuenciales necesitarán moldes suplementarios.

Tendré que mantener las cosas simples. ¿Alguna sugerencia?

+1

¿Cómo está exactamente transfiriendo cadenas a otros tipos de datos? –

+1

¿estás hablando de casting o de análisis sintáctico? – fortran

+0

Es más complicado. No es exactamente un elenco de/a String, hay una interfaz de Fila y más implementaciones. Cada implementación es como un contenedor, que devuelve un objeto. Ese objeto debe ser lanzado. Si tengo que hacer algunos cambios en una Fila específica, se necesitan algunos moldes en el mecanismo interno. –

Respuesta

8

La conversión no cambia la cantidad de memoria que ocupa un objeto. Simplemente cambia el tipo de tiempo de ejecución.

Si puede hacer esas operaciones por fila, simplemente haga la operación inmediatamente dentro del bucle en el que lee una sola línea.

while ((line = reader.readLine()) != null) { 
    line = process(line); 
    writer.println(line); 
} 

De esta manera se termina efectivamente con una sola línea en la memoria de Java cada vez de todo el archivo.

O si lo tiene que hacer esas operaciones sobre la base de todo el archivo CSV (es decir, aquellas operaciones dependen de todos filas), a continuación, su apuesta más eficiente es importar el archivo CSV en una base de datos SQL real y luego usa instrucciones SQL para alterar los datos y luego exportarlos a un archivo CSV de nuevo.

3

Recomendaría usar un MappedByteBuffer (de NIO), que puede usar para leer un archivo demasiado grande para caber en la memoria. Cartografía solo una región del archivo en la memoria; una vez que haya terminado de leer esta región (por ejemplo, los primeros 10k), asigne el siguiente, y así sucesivamente, hasta que haya leído todo el archivo. Memoria eficiente y bastante fácil de implementar.

2

Java yesos: como

Object a = new String(); 
String b (String) a; 

no son caros. - No importa si lanzas cadenas o cualquier otro tipo.

1

Su valor real agregado será leer cada línea como una Cadena, lo cual es bastante fácil en Java.Después de que está en una cadena, es trivial para dividir la cadena en cada coma con

String[] row = parsedRow.split(",");

El tendrá una cadena para cada valor de la matriz, que puede ser operado.

+0

Considere lo que su llamada 'split()' hará a '123," abc, def ", ghi'. –

+0

@JUST MI OPINIÓN correcta - debidamente anotado, pero luego estás empezando a entrar en un caso marginal dado mi ejemplo simplista que supone que una coma siempre será un separador y nunca estará dentro de una Cadena. – bakoyaro

Cuestiones relacionadas