Escáner de Java

1. Descripción general del escáner

En este tutorial rápido, ilustraremos cómo usar la clase Java Scanner para leer la entrada, buscar y omitir patrones con diferentes delimitadores.

2. Escanear un archivo

Primero, veamos cómo leer un archivo usando Scanner .

En el siguiente ejemplo, leemos que un archivo contiene " Hola mundo " en tokens:

@Test public void whenReadFileWithScanner_thenCorrect() throws IOException{ Scanner scanner = new Scanner(new File("test.txt")); assertTrue(scanner.hasNext()); assertEquals("Hello", scanner.next()); assertEquals("world", scanner.next()); scanner.close(); }

Tenga en cuenta que el método next () devuelve el siguiente token de cadena aquí.

Además, observe cómo cerramos el escáner cuando terminamos de usarlo.

3. Convertir InputStream en String

A continuación, veamos cómo convertir un InputStream en un String usando un escáner :

@Test public void whenConvertInputStreamToString_thenConverted() throws IOException { String expectedValue = "Hello world"; FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); scanner.useDelimiter("A"); String result = scanner.next(); assertEquals(expectedValue, result); scanner.close(); }

Al igual que en el ejemplo anterior, utilizamos el escáner para tokenizar todo el flujo desde el principio hasta la siguiente expresión regular "A", que coincide con la entrada completa.

4. Escáner frente a lector con búfer

Ahora, analicemos la diferencia entre Scanner y BufferedReader , generalmente usamos:

  • BufferedReader cuando queremos leer la entrada en líneas
  • Escáner para leer la entrada en tokens.

En el siguiente ejemplo, estamos leyendo un archivo en líneas usando BufferedReader :

@Test public void whenReadUsingBufferedReader_thenCorrect() throws IOException { String firstLine = "Hello world"; String secondLine = "Hi, John"; BufferedReader reader = new BufferedReader(new FileReader("test.txt")); String result = reader.readLine(); assertEquals(firstLine, result); result = reader.readLine(); assertEquals(secondLine, result); reader.close(); }

Ahora, usemos Scanner para leer el mismo archivo en tokens:

@Test public void whenReadUsingScanner_thenCorrect() throws IOException { String firstLine = "Hello world"; FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); String result = scanner.nextLine(); assertEquals(firstLine, result); scanner.useDelimiter(", "); assertEquals("Hi", scanner.next()); assertEquals("John", scanner.next()); scanner.close(); }

Nota cómo estamos utilizando el escáner nextLine () API - para leer toda la línea .

5. Escanear la entrada desde la consola con un nuevo escáner (System.in)

A continuación, veamos cómo leer la entrada de la consola usando una instancia de escáner :

@Test public void whenReadingInputFromConsole_thenCorrect() { String input = "Hello"; InputStream stdin = System.in; System.setIn(new ByteArrayInputStream(input.getBytes())); Scanner scanner = new Scanner(System.in); String result = scanner.next(); assertEquals(input, result); System.setIn(stdin); scanner.close(); }

Tenga en cuenta que usamos System.setIn (…) para simular alguna entrada procedente de la consola.

5.1. API nextLine ()

Este método simplemente devuelve la cadena en la línea actual:

scanner.nextLine();

Esto lee el contenido de la línea actual y lo devuelve excepto por cualquier separador de línea al final, en este caso, el carácter de nueva línea.

Después de leer el contenido, Scanner establece su posición al comienzo de la siguiente línea. El punto importante a recordar es que la API nextLine () consume el separador de línea y mueve la posición del escáner a la siguiente línea .

Entonces, la próxima vez que leamos Scanner, lo estaremos leyendo desde el comienzo de la siguiente línea.

5.2. nextInt () API

Este método escanea el siguiente token de la entrada como un int:

scanner.nextInt();

La API lee el token entero disponible a continuación.

En este caso, si el siguiente token es un número entero y después del entero hay un separador de línea, recuerde siempre que nextInt () no consumirá el separador de línea. En cambio, la posición del escáner será el propio separador de líneas .

Entonces, si tenemos una serie de operaciones, donde la primera operación es un scanner.nextInt () y luego un scanner.nextLine () y como entrada si proporcionamos un número entero y presionamos un salto de línea, ambas operaciones se ejecutarán.

La API nextInt () consumirá el entero y la API nextLine () consumirá el separador de línea y colocará Scanner al comienzo de la siguiente línea.

6. Validar entrada

Ahora, veamos cómo validar la entrada usando un escáner . En el siguiente ejemplo, usamos el método del escáner hasNextInt () para verificar si la entrada es un valor entero:

@Test public void whenValidateInputUsingScanner_thenValidated() throws IOException { String input = "2000"; InputStream stdin = System.in; System.setIn(new ByteArrayInputStream(input.getBytes())); Scanner scanner = new Scanner(System.in); boolean isIntInput = scanner.hasNextInt(); assertTrue(isIntInput); System.setIn(stdin); scanner.close(); }

7. Escanear una cadena

A continuación, veamos cómo escanear una cadena usando Scanner :

@Test public void whenScanString_thenCorrect() throws IOException { String input = "Hello 1 F 3.5"; Scanner scanner = new Scanner(input); assertEquals("Hello", scanner.next()); assertEquals(1, scanner.nextInt()); assertEquals(15, scanner.nextInt(16)); assertEquals(3.5, scanner.nextDouble(), 0.00000001); scanner.close(); }

Nota: El método nextInt (16) lee el siguiente token como un valor entero hexadecimal.

8. Encontrar patrón

Ahora, veamos cómo encontrar un patrón usando Scanner .

En el siguiente ejemplo, usamos findInLine () para buscar un token que coincida con el Patrón dado en toda la entrada:

@Test public void whenFindPatternUsingScanner_thenFound() throws IOException { String expectedValue = "world"; FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); String result = scanner.findInLine("wo..d"); assertEquals(expectedValue, result); scanner.close(); }

We can also search for a Pattern in the specific domain using findWithinHorizon() as in the following example:

@Test public void whenFindPatternInHorizon_thenFound() throws IOException { String expectedValue = "world"; FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); String result = scanner.findWithinHorizon("wo..d", 5); assertNull(result); result = scanner.findWithinHorizon("wo..d", 100); assertEquals(expectedValue, result); scanner.close(); }

Note that the search horizon is simply the number of characters within which the search is performed.

9. Skip Pattern

Next – let's see how to skip a Pattern in Scanner. We can skip tokens that match a specific pattern while reading the input using Scanner.

In the following example – we skip “Hello” token using the Scanner method skip():

@Test public void whenSkipPatternUsingScanner_thenSkipped() throws IOException { FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); scanner.skip(".e.lo"); assertEquals("world", scanner.next()); scanner.close(); }

10. Change Scanner Delimiter

Finally – let's see how to change the Scanner delimiter. In the following example – we change the default Scanner delimiter to “o“:

@Test public void whenChangeScannerDelimiter_thenChanged() throws IOException { String expectedValue = "Hello world"; String[] splited = expectedValue.split("o"); FileInputStream inputStream = new FileInputStream("test.txt"); Scanner scanner = new Scanner(inputStream); scanner.useDelimiter("o"); assertEquals(splited[0], scanner.next()); assertEquals(splited[1], scanner.next()); assertEquals(splited[2], scanner.next()); scanner.close(); }

We can also use multiple delimiters. In the following example – we use both commas “,” and dash”” as delimiters to scan a file contains “John,Adam-Tom“:

@Test public void whenReadWithScannerTwoDelimiters_thenCorrect() throws IOException -"); assertEquals("John", scanner.next()); assertEquals("Adam", scanner.next()); assertEquals("Tom", scanner.next()); scanner.close(); 

Note: The default Scanner delimiter is whitespace.

11. Conclusion

In this tutorial, we went over multiple real-world examples of using the Java Scanner.

Aprendimos a leer la entrada desde un archivo, consola o cadena usando Scanner ; también aprendimos cómo encontrar y omitir un patrón usando Scanner , así como también cómo cambiar el delimitador de Scanner .

La implementación de estos ejemplos se puede encontrar en GitHub.