Сканер Java

Java сканер

1. обзор

В этом руководстве мы покажем, как использоватьJava Scanner для чтения ввода, а также для поиска и пропуска шаблонов с разными разделителями.

2. Сканировать файл

Во-первых, давайте посмотрим, как читать файл с помощьюScanner. В следующем примере мы читаем файл, содержащий «Hello world», в токены, используяScanner:

@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();
}

Примечание. МетодScannernext() возвращает следующий токенString.

3. ПреобразоватьInputStream вString

Далее - давайте посмотрим, как преобразоватьInputStream вString с помощьюScanner:

@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();
}

Примечание. В предыдущем примере мы обманулиScanner, чтобы токенизировать весь поток от начала до следующего регулярного выражения «A» (которое соответствует началу ввода).

4. Scanner vs. BufferedReader

Теперь - давайте обсудим разницу междуScanner иBufferedReader - мы обычно используем:

  • BufferedReader, когда мы хотим прочитать вводinto lines

  • Scanner для чтения вводаinto tokens

В следующем примере мы читаем файл по строкам, используя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();
}

Теперь давайте воспользуемсяScanner для чтения того же файла в токены:

@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();
}

Примечание. Мы также можем использовать APIScannernextLine() для чтения всей строки.

5. Сканировать ввод из консоли с помощьюNew Scanner(System.in)

Далее - давайте посмотрим, как читать ввод из консоли с помощьюScanner:

@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();
}

Обратите внимание, что мы использовалиSystem.setIn(…) для имитации некоторого ввода, поступающего из консоли.

5.1. nextLine() API

Этот метод просто возвращает строку в текущей строке:

scanner.nextLine();

Это читает содержимое текущей строки и возвращает его за исключением любого разделителя строк в конце - в данном случае - символа новой строки.

После чтения содержимогоScanner устанавливает свою позицию в начало следующей строки. Важно помнить, чтоnextLine() API consumes the line separator and moves the position of the Scanner to the next line.

Так что в следующий раз, если мы прочитаемScanner, мы будем читать с начала следующей строки.

5.2. nextInt() API

Этот метод сканирует следующий токен ввода какint:

scanner.nextInt();

API читает следующий целочисленный токен. В этом случае, если следующий токен является целым числом и после целого числа стоит разделитель строк, всегда помните, чтоnextInt() will not consume the line separator. Instead, the position of the scanner will be the line separator itself.

Итак, если у нас есть серия операций, где первая операция - этоscanner.nextInt(), а затемscanner.nextLine(), и в качестве входных данных, если мы предоставим целое число и нажмем разрыв строки, обе операции будут выполнены.

APInextInt() будет использовать целое число, а APInextLine() будет использовать разделитель строк и поместитScanner в начало следующей строки.

6. Подтвердить ввод

А теперь давайте посмотрим, как проверить ввод с помощьюScanner. В следующем примере мы используем методScannerhasNextInt(), чтобы проверить, является ли ввод целочисленным значением:

@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. Сканировать aString

Далее - давайте посмотрим, как сканироватьString с помощью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();
}

Примечание. МетодnextInt(16) считывает следующий токен как шестнадцатеричное целое число.

8. НайдитеPattern

А теперь давайте посмотрим, как найтиPattern с помощьюScanner.

В следующем примере - мы используем отfindInLine() доsearch for a token that matches the given Pattern во всем вводе:

@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();
}

Мы также можем искатьPattern в конкретном домене, используяfindWithinHorizon(), как в следующем примере:

@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();
}

Обратите внимание, чтоsearch horizon is simply the number of characters, в котором выполняется поиск.

9. ПропуститьPattern

Далее - давайте посмотрим, как пропуститьPattern вScanner. Мы можем пропустить токены, соответствующие определенному шаблону, при чтении ввода с помощьюScanner.

В следующем примере мы пропускаем токен «Hello» с помощью методаScannerskip():

@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. Изменить разделительScanner

Наконец, давайте посмотрим, как изменить разделительScanner. В следующем примере мы меняем разделитель по умолчаниюScanner на «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();
}

Мы также можем использовать несколько разделителей. В следующем примере - мы используем запятую «,» и тире «» в качестве разделителей для сканирования файла, содержащего «John,Adam-Tom»:

@Test
public void whenReadWithScannerTwoDelimiters_thenCorrect()
  throws IOException {
    Scanner scanner = new Scanner(new File("test.txt"));
    scanner.useDelimiter(",|-");

    assertEquals("John", scanner.next());
    assertEquals("Adam", scanner.next());
    assertEquals("Tom", scanner.next());

    scanner.close();
}

Примечание.default Scanner delimiter - это пробел.

11. Заключение

В этом руководстве мы рассмотрели несколько реальных примеров использованияJava Scanner.

Мы узнали, как читать ввод из файла, консоли илиString, используяScanner; мы также узнали, как найти и пропустить шаблон с помощьюScanner, а также как изменить разделительScanner.

Реализацию этих примеров можно найти вover on GitHub - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.