java - solo - ¿Qué son las marcas y los reinicios en BufferedReader?
qué hacer cuando mi pc se reinicia sola (6)
Aquí hay un ejemplo.
int bufferSize = 4;
int readLimit = 4
ByteArrayInputStream byteInputStream = new ByteArrayInputStream("123456789abcdef".getBytes());
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(byteInputStream, bufferSize)) {
bufferedInputStream.mark(readLimit);
System.out.print((char) bufferedInputStream.read());//byte1
System.out.print((char) bufferedInputStream.read());//byte2
System.out.print((char) bufferedInputStream.read());//byte3
System.out.print((char) bufferedInputStream.read());//byte4
bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());//byte5
// Using this next reset() instead of the first one will throw an exception
// bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
}
Salida: 12341234
Para el propósito de readLimit
, here''s una buena referencia.
Me gustaría saber cuáles son los métodos mark()
y reset()
de BufferedReader
? ¿Cómo los uso? Leí el Javadoc pero como principiante no pude entenderlo.
Imagina que tienes los siguientes caracteres en el BufferReader = "123456789", si marcas en la posición 4 con respecto al carácter ''5'' y luego reinicias tu BufferReader, terminarás con 12345.
La mark()
marca un punto particular en una secuencia y reset()
restablece la secuencia a la marca más reciente. Estos métodos proporcionan una función de book-marking
que le permite leer con anticipación en la secuencia para inspeccionar los próximos datos.
De esta documentation:
El método mark () marca una posición en la entrada a la que se puede "reiniciar" el flujo llamando al método reset (). El parámetro readLimit es el número de caracteres que se pueden leer desde la secuencia después de establecer la marca antes de que la marca se convierta en inválida. Por ejemplo, si se llama a mark () con un límite de lectura de 10, cuando se leen 11 caracteres de la secuencia antes de llamar al método reset (), entonces la marca no es válida y no se requiere la instancia del objeto de la secuencia. recuerda la marca Tenga en cuenta que el número de caracteres que pueden recordarse con este método puede ser mayor que el tamaño del búfer de lectura interno. Tampoco depende de la secuencia subordinada que admite la función de marca / reinicio.
La interfaz del lector no te deja volver, solo puedes leer. BufferedReader, por otro lado, crea un búfer, por lo que puedes regresar un poco al leer. Y para eso son esos métodos.
Con el método mark () usted pone un "marcador" en una posición, luego puede seguir leyendo. Una vez que te das cuenta de que quieres devolver la posición marcada, usas reset () para eso. Y desde ese punto vuelves a leer los mismos valores. Puedes usarlo para lo que quieras.
Los métodos de mark
y reset
flujos proporcionan una forma de saltar hacia atrás en el flujo y releer los datos.
Cuando llame a mark()
en un BufferedReader
, comenzará a guardar los datos que lea desde ese punto en su búfer interno. Cuando se llama a reset()
, volverá a la posición marcada de la transmisión, de modo que el búfer en memoria satisfará las siguientes read()
. Cuando lea más allá del final de ese búfer, entonces volverá a leer datos nuevos sin problemas. BufferedInputStream
funciona de la misma manera.
El parámetro int para mark
le indica el número máximo de caracteres (para BufferedReader
) o bytes (para BufferedInputStream
) que desea que pueda ir hacia atrás. Si lee demasiados datos más allá de la posición marcada, entonces la marca se puede "invalidar", y la llamada a reset()
fallará con una excepción.
Un pequeño ejemplo:
BufferedReader r = new BufferedReader(new StringReader(
"Happy Birthday to You!/n" +
"Happy Birthday, dear " + System.getProperty("user.name") + "!"));
r.mark(1000); // save the data we are about to read
System.out.println(r.readLine()); // read the first line
r.reset(); // jump back to the marked position
r.mark(1000); // start saving the data again
System.out.println(r.readLine()); // read the first line again
System.out.println(r.readLine()); // read the second line
r.reset(); // jump back to the marked position
System.out.println(r.readLine()); // read the first line one final time
En ese ejemplo, envolví el StringReader
en un BufferedReader
para obtener el método readLine()
, ¡pero el StringReader
ya admite la mark
y se reset
por sí mismo! Las secuencias que se leen desde una fuente de datos en memoria generalmente admiten la mark
y el reset
, ya que ya tienen todos los datos en la memoria, por lo que es fácil para ellos leerlos nuevamente. Las secuencias que se leen desde archivos o tuberías o sockets de red no son compatibles con la mark
y el reset
, pero siempre puede agregar esa característica a cualquier secuencia envolviéndola en un BufferedInputStream
o BufferedReader
.
Reader::mark(int readLimit)
documentación dice:
Establece una posición de marca en este lector. El parámetro readLimit indica cuántos caracteres se pueden leer antes de que se invalide la marca . Si se restablece (), el lector volverá a posicionarse en la posición marcada si no se ha superado el límite de lectura.
Ejemplo:
import java.io.*;
import static java.lang.System.out;
public class App {
public static final String TEST_STR = "Line 1/nLine 2/nLine 3/nLine 4/n";
public static void main(String[] args) {
try (BufferedReader in = new BufferedReader(new StringReader(TEST_STR))) {
// first check if this Reader support mark operation
if (in.markSupported()) {
out.println(in.readLine());
in.mark(0); // mark ''Line 2''
out.println(in.readLine());
out.println(in.readLine());
in.reset(); // reset ''Line 2''
out.println(in.readLine());
in.reset(); // reset ''Line 2''
out.println(in.readLine());
in.mark(0); // mark ''Line 3''
out.println(in.readLine());
in.reset(); // reset ''Line 3''
out.println(in.readLine());
out.println(in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Salida:
Line 1
Line 2
Line 3
Line 2
Line 2
Line 3
Line 3
Line 4