Escáner frente a BufferedReader


284

Hasta donde sé, los dos métodos más comunes para leer datos basados ​​en caracteres de un archivo en Java están utilizando Scannero BufferedReader. También sé que BufferedReaderlee los archivos de manera eficiente mediante el uso de un búfer para evitar las operaciones físicas del disco.

Mis preguntas son:

  • ¿ ScannerFunciona tan bien como BufferedReader?
  • ¿Por qué elegirías Scannermás BufferedReadero viceversa?

1
En general, también uso el escáner para leer desde el estándar en ('Scanner in = new Scanner (System.in)' se siente mucho más limpio). No estoy seguro de si eso es realmente menos eficiente, pero dado que leer desde std in está bloqueando, no puedo imaginar que la eficiencia de Scanner sea el problema.
dimo414

Respuestas:


201

Scannerse usa para analizar tokens del contenido de la secuencia mientras BufferedReadersolo lee la secuencia y no realiza ningún análisis especial.

De hecho, puede pasar a BufferedReadera a scannercomo fuente de caracteres para analizar.


55
BufferedReader está sincronizado y Scanner no, por lo que depende de usted decidir.
Rubén

1
Sé que este tema es antiguo, pero he tenido resultados mixtos entre los sistemas operativos que usan BufferedReader al intentar extraer contenido de las secuencias proporcionadas por Process (es decir, capturar la salida de un comando externo). Una vez que cambié mi código para usar Scanner, como se señaló en una respuesta separada , las cosas comenzaron a comportarse de manera consistente y como se esperaba.
ewh

@Reuben But Scannerdepende en última instancia de otra cosa para su entrada, que bien puede estar sincronizada.
Marqués de Lorne

189

En la última versión / compilación de JDK6 (b27), Scannertiene un búfer más pequeño ( 1024 caracteres ) en comparación con BufferedReader( 8192 caracteres ), pero es más que suficiente.

En cuanto a la elección, use el Scannersi desea analizar el archivo, use el BufferedReadersi desea leer el archivo línea por línea. Consulte también el texto introductorio de sus documentaciones API anteriormente vinculadas.

  • Parsing = interpretar la entrada dada como tokens (partes). Es capaz de devolverle partes específicas directamente como int, string, decimal, etc. Vea también todos esos nextXxx()métodos en Scannerclase.
  • Lectura = transmisión tonta. Sigue devolviéndote todos los personajes, que a su vez debes inspeccionar manualmente si deseas unir o componer algo útil. Pero si no necesita hacer eso de todos modos, entonces la lectura es suficiente.

1
Buena esa. Gracias por la punta del búfer. Lo estuve buscando todo el tiempo ya que las lecturas nativas son extremadamente caras.
Achow

77
@Asif: parsing = interpretar la entrada dada como tokens (partes). Es capaz de devolverle partes específicas directamente como int, string, decimal, etc. Vea también todos los métodos nextXxx () en la clase Scanner. Lectura = transmisión tonta. Sigue devolviéndote todos los personajes, que a su vez debes inspeccionar manualmente si deseas unir o componer algo útil. Pero si no necesita hacer eso de todos modos, entonces la lectura es suficiente.
BalusC

@BalusC Ok, ya lo usé, readInt();readFloat (); etc. Ahora tengo lo que es el medio de análisis. y BalusC, ¿puedes darme poco tiempo solo 10 minutos en la sala de chat? Quiero preguntar un poco sobre el almacenamiento intermedio, cómo funciona.
Asif Mushtaq

¿Qué envuelvo BufferedReaderen el constructor de Scanner? ¿Es esta una buena idea?
vivek

1
ScannerEl búfer se expandirá según sea necesario para la coincidencia de patrones. Entonces, si desea un búfer más grande, solo necesita invocar, por ejemplo findWithinHorizon("\\z", 8192), en él y luego, usará un búfer con capacidad de 8192caracteres (o el archivo completo si es más pequeño que eso).
Holger

77

Vea este enlace , a continuación se cita desde allí:

Un BufferedReader es una clase simple destinada a leer eficientemente desde la secuencia subyacente. En general, cada solicitud de lectura realizada por un lector como un FileReader hace que se realice una solicitud de lectura correspondiente a la secuencia subyacente. Cada invocación de read () o readLine () podría hacer que los bytes se lean del archivo, se conviertan en caracteres y luego se devuelvan, lo que puede ser muy ineficiente. La eficiencia mejora notablemente si un Reader se deforma en un BufferedReader.

BufferedReader está sincronizado, por lo que las operaciones de lectura en un BufferedReader se pueden realizar de forma segura desde varios subprocesos.

Por otro lado, un escáner tiene mucho más queso incorporado; puede hacer todo lo que un BufferedReader puede hacer y al mismo nivel de eficiencia también. Sin embargo, además, un escáner puede analizar la secuencia subyacente para tipos y cadenas primitivos utilizando expresiones regulares. También puede tokenizar la secuencia subyacente con el delimitador de su elección. ¡También puede hacer un escaneo directo de la secuencia subyacente sin tener en cuenta el delimitador!

Sin embargo, un escáner no es seguro para subprocesos, tiene que estar sincronizado externamente.

La elección de usar un BufferedReader o un Scanner depende del código que esté escribiendo, si está escribiendo un lector de registro simple El lector Buffer es adecuado. Sin embargo, si está escribiendo un analizador XML, el escáner es la opción más natural.

Incluso mientras lee la entrada, si desea aceptar la entrada del usuario línea por línea y decir simplemente agregarla a un archivo, un BufferedReader es lo suficientemente bueno. Por otro lado, si desea aceptar la entrada del usuario como un comando con múltiples opciones, y luego tiene la intención de realizar diferentes operaciones basadas en el comando y las opciones especificadas, un escáner se adaptará mejor.


"Un escáner, por otro lado, tiene mucho más queso incorporado; puede hacer todo lo que puede hacer un BufferedReader y al mismo nivel de eficiencia". No está de acuerdo, BufferedReader es un poco más rápido en comparación con Scanner porque Scanner analiza los datos de entrada y BufferedReader simplemente lee la secuencia de caracteres.
Pratik

40
  1. BufferedReadertiene una memoria de búfer significativamente mayor que Scanner. Úselo BufferedReadersi desea obtener cadenas largas de una secuencia, y utilícelo Scannersi desea analizar un tipo específico de token de una secuencia.

  2. Scannerpuede usar tokenize usando delimitador personalizado y analizar la secuencia en tipos primitivos de datos, mientras BufferedReaderque solo puede leer y almacenar String.

  3. BufferedReaderes sincrónico mientras Scannerque no lo es. Úselo BufferedReadersi está trabajando con múltiples hilos.

  4. Scanneroculta IOException mientras la BufferedReaderarroja de inmediato.


18

Sugiero usar BufferedReaderpara leer texto. Scannerse esconde IOExceptionmientras lo BufferedReadertira de inmediato.


12

Las diferencias entre BufferedReader y Scanner son las siguientes:

  1. BufferedReader está sincronizado pero el escáner no está sincronizado .
  2. BufferedReader es seguro para subprocesos pero el escáner no es seguro para subprocesos .
  3. BufferedReader tiene una memoria buffer más grande pero el escáner tiene una memoria buffer más pequeña .
  4. BufferedReader es más rápido, pero el escáner es más lento en la ejecución .
  5. Código para leer una línea desde la consola:

    BufferedReader :

     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br= new BufferedReader(isr);
     String st= br.readLine();

    Escáner :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();

8

Las siguientes son las diferencias entre BufferedReader y Scanner

  1. BufferedReader solo lee datos, pero el escáner también analiza datos.
  2. solo puedes leer String usando BufferedReader, pero puedes leer int, long o float usando Scanner.
  3. BufferedReader es anterior a Scanner, existe desde jdk 1.1 mientras que Scanner fue agregado en la versión JDK 5.
  4. El tamaño del búfer de BufferedReader es grande (8 KB) en comparación con 1 KB de escáner.
  5. BufferedReader es más adecuado para leer archivos con cadenas largas, mientras que Scanner es más adecuado para leer pequeñas entradas de usuario desde el símbolo del sistema.
  6. BufferedReader está sincronizado pero Scanner no, lo que significa que no puede compartir Scanner entre múltiples hilos.
  7. BufferedReader es más rápido que Scanner porque no pasa mucho tiempo analizando
  8. BufferedReader es un poco más rápido en comparación con Scanner
  9. BufferedReader es del paquete java.io y Scanner es del paquete java.util en función de los puntos que podemos seleccionar.

Gracias


6

Las principales diferencias:

  1. Escáner

  • Un escáner de texto simple que puede analizar tipos y cadenas primitivos utilizando expresiones regulares.
  • Un escáner divide su entrada en tokens utilizando un patrón delimitador, que por defecto coincide con los espacios en blanco. Los tokens resultantes se pueden convertir en valores de diferentes tipos utilizando los siguientes métodos.

Ejemplo

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

imprime el siguiente resultado:

 1
 2
 red
 blue 

Se puede generar la misma salida con este código, que utiliza una expresión regular para analizar los cuatro tokens a la vez:

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i=1; i<=result.groupCount(); i++)
     System.out.println(result.group(i));
 s.close(); `


  1. BufferedReader:

    • Lee texto de una secuencia de entrada de caracteres, almacenando caracteres en búfer para proporcionar una lectura eficiente de caracteres, matrices y líneas.

    • Se puede especificar el tamaño del búfer o se puede usar el tamaño predeterminado. El valor predeterminado es lo suficientemente grande para la mayoría de los propósitos.

En general, cada solicitud de lectura realizada por un lector hace que se realice una solicitud de lectura correspondiente del carácter subyacente o flujo de bytes. Por lo tanto, es aconsejable envolver un BufferedReader alrededor de cualquier lector cuyas operaciones read () puedan ser costosas, como FileReaders y InputStreamReaders. Por ejemplo,

BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));

almacenará en búfer la entrada del archivo especificado. Sin almacenamiento en búfer, cada invocación de read () o readLine () podría hacer que los bytes se lean del archivo, se conviertan en caracteres y luego se devuelvan, lo que puede ser muy ineficiente. Los programas que usan DataInputStreams para la entrada de texto se pueden localizar reemplazando cada DataInputStream con un BufferedReader apropiado.

Fuente: Enlace


3

Hay diferentes formas de tomar entrada en Java como:

1) BufferedReader 2) Escáner 3) Argumentos de línea de comando

BufferedReader Lee el texto de una secuencia de entrada de caracteres, almacenando caracteres en búfer para proporcionar una lectura eficiente de caracteres, matrices y líneas.

Where Scanner es un escáner de texto simple que puede analizar tipos y cadenas primitivos utilizando expresiones regulares.

si está escribiendo un lector de registro simple El lector con buffer es adecuado. Si está escribiendo un analizador XML, el escáner es la opción más natural.

Para más información, consulte:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69


1

La siguiente respuesta está tomada de la lectura desde la consola: JAVA Scanner vs BufferedReader

Cuando se lee una entrada desde la consola, existen dos opciones para lograrlo. Primero usando Scanner, otro usando BufferedReader. Ambos tienen características diferentes. Significa diferencias en cómo usarlo.

El escáner trató la entrada dada como token. BufferedReader solo lee línea por línea la entrada dada como cadena. El escáner proporciona capacidades de análisis al igual que nextInt (), nextFloat ().

Pero, ¿entre qué hay otras diferencias?

  • El escáner trató la entrada dada como token. BufferedReader como línea de secuencia / cadena
  • El escáner tokenizó la entrada dada utilizando expresiones regulares. El uso de BufferedReader debe escribir código adicional
  • BufferedReader más rápido que el escáner * punto no. 2
  • El escáner no está sincronizado, BufferedReader sincronizado

El escáner viene con JDK versión 1.5 superior.

¿Cuándo se debe usar el escáner o el lector protegido?

Observe las principales diferencias entre ambos, uno con tokenizado y otros con línea de transmisión. Cuando necesite capacidades de análisis, use Scanner en su lugar. Pero, estoy más cómodo con BufferedReader. Cuando necesite leer un archivo, use BufferedReader, porque es usar buffer cuando lee un archivo. O puede usar BufferedReader como entrada al escáner.


0
  1. BufferedReader probablemente le brindará un mejor rendimiento (porque Scanner se basa en InputStreamReader, consulte las fuentes). ups, para leer archivos utiliza nio. Cuando probé el rendimiento de nio contra el rendimiento de BufferedReader para archivos grandes, nio muestra un rendimiento un poco mejor.
  2. Para leer del archivo, pruebe Apache Commons IO.

0

Prefiero Scannerporque no arroja excepciones marcadas y, por lo tanto, su uso da como resultado un código más simplificado.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.