2008-11-04 37 views
24

Actualmente tengo 2 BufferedReader inicializados en el mismo archivo de texto. Cuando termine de leer el archivo de texto con el primer BufferedReader, utilizo el segundo para hacer otro pase desde arriba. Múltiples pasadas a través del mismo archivo son necesarias.Java BufferedReader volver al principio de un archivo de texto?

Sé acerca de reset(), pero debe ir precedido de las llamadas mark() y mark() para conocer el tamaño del archivo, algo con lo que no creo que deba preocuparme.

Ideas? Paquetes? Libs? ¿Código?

Gracias TJ

Respuesta

24

¿Cuál es la desventaja de sólo la creación de un nuevo BufferedReader para leer desde la parte superior? Esperaría que el sistema operativo guarde en caché el archivo si es lo suficientemente pequeño.

Si le preocupa el rendimiento, ¿ha demostrado que es un cuello de botella? Simplemente haría lo más simple y no me preocupara hasta que tengas una razón específica para hacerlo. Quiero decir, podrías leer todo en la memoria y luego hacer los dos pasos en el resultado, pero de nuevo, eso será más complicado que leer desde el principio con un nuevo lector.

27

Los lectores almacenados en búfer deben leer un archivo secuencialmente. Lo que está buscando es java.io.RandomAccessFile, y luego puede usar seek() para llevarlo a donde desee en el archivo.

El lector de acceso aleatorio se implementa de esta manera:

try{ 
    String fileName = "c:/myraffile.txt"; 
    File file = new File(fileName); 
    RandomAccessFile raf = new RandomAccessFile(file, "rw"); 
    raf.readChar(); 
    raf.seek(0); 
} catch (FileNotFoundException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

El "rw" es un personaje que es el modo detailed here.

La razón por la que los lectores de acceso secuencial están configurados de esta manera es para que puedan implementar sus almacenamientos intermedios y que las cosas no se puedan cambiar bajo sus pies. Por ejemplo, el lector de archivos que se le da al lector de búfer solo debe ser operado por ese lector de búfer. Si hubiera otra ubicación que podría afectarlo, podría tener una operación incoherente, ya que un lector avanzó su posición en el lector de archivos mientras que el otro quería que no cambiara, ahora usa el otro lector y está en una ubicación indeterminada.

3

La mejor manera de proceder es cambiar su algoritmo, de forma que NO necesite el segundo pase. Usé este enfoque un par de veces, cuando tuve que lidiar con archivos enormes (pero no terribles, es decir, pocos GB) que no se ajustaban a la memoria disponible.

Puede ser difícil, pero la ganancia de rendimiento por lo general worths el esfuerzo

+0

¿Podría dar más detalles? Tengo un archivo que pesa 30 MB, no puedo cargarlo todo en la memoria. He ordenado los datos y ahora quiero hacer una búsqueda binaria directamente en el archivo. Para esto necesito buscar al azar. –

+0

Hoy en día supongo que te refieres a 30GB, a menos que estés usando hw realmente pequeño (pero sin disco) De todos modos, las búsquedas aleatorias en discos a menudo arruinan por completo el rendimiento logarítmico de la búsqueda binaria. Un par de alternativas son 1) hacer acceso secuencial (sí, en el disco una búsqueda secuencial puede ser más rápida que una búsqueda binaria) o 2) un enfoque mixto, como usar B-tree http://en.wikipedia.org/wiki/ B-tree Si estas sugerencias no son suficientes, es posible que desee plantear su pregunta como una pregunta separada en lugar de un comentario (por favor, publique un comentario aquí con un enlace a la pregunta para enviarnos un ping) – Davide

-1

"El conjunto de negocios sobre la marca() y reset() en BufferedReader huele mal diseño."

por qué no extiende esta clase y hace que marque() en el constructor() y luego haga una búsqueda (0) en el método topOfFile().

BR,
~ Un

1

Acerca de la marca/reset:

El método de marca en BufferedReader toma un parámetro readAheadLimit que limita hasta dónde se puede leer después de un signo antes del reinicio se hace imposible.Restablecer no significa en realidad una búsqueda de sistema de archivos (0), solo busca dentro del búfer. Para citar el Javadoc:

readAheadLimit: límite en el número de caracteres que se pueden leer conservando la marca. Después de leer tantos caracteres, intentar restablecer la secuencia puede fallar. Un valor límite mayor que el tamaño del búfer de entrada provocará que se asigne un nuevo búfer cuyo tamaño no sea inferior al límite. Por lo tanto, los valores grandes deben usarse con cuidado.

Cuestiones relacionadas