Java BufferedReader volver a la parte superior de un archivo de texto?

Actualmente tengo 2 BufferedReader s 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.

Sé sobre el reset() , pero debe ir precedido de la mark() y mark() necesita saber el tamaño del archivo, algo con lo que no creo que deba preocuparme.

Ideas? Paquetes? Libs? ¿Código?

Gracias TJ

¿Cuál es la desventaja de simplemente crear 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.

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 quiere en el archivo.

El lector de acceso aleatorio se implementa así:

 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 carácter de modo que se detalla aquí .

La razón por la que los lectores de acceso secuencial están configurados de esta manera es para que puedan implementar sus búferes y que las cosas no se puedan cambiar por debajo de 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.

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 generalmente vale la pena el esfuerzo

Acerca de mark / reset:

El método de marca en BufferedReader toma un parámetro readAheadLimit que limita qué tan lejos puede leer después de una marca antes de que el restablecimiento se vuelva 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: limita el número de caracteres que se pueden leer mientras se conserva 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.

“Todo el asunto sobre mark () y reset () en BufferedReader huele a diseño pobre”.

¿Por qué no extiendes esta clase y haces que marque () en el constructor () y luego haces una búsqueda (0) en el método topOfFile ()?

BR,
~ A