Javaスキャナー

Javaスキャナー

1. 概要

このチュートリアルでは、Java Scannerを使用して入力を読み取り、さまざまな区切り文字を使用してパターンを検索してスキップする方法を説明します。

2. ファイルをスキャンする

まず、Scannerを使用してファイルを読み取る方法を見てみましょう。 次の例では、Scannerを使用して、「Hello world」を含むファイルをトークンに読み込みます。

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

注:Scannerメソッドnext()は、次のStringトークンを返します。

3. InputStreamStringに変換します

次へ–Scannerを使用してInputStreamStringに変換する方法を見てみましょう。

@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対。 BufferedReader

ここで、ScannerBufferedReaderの違いについて説明しましょう。通常は次のものを使用します。

  • 入力into linesを読み取りたい場合はBufferedReader

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

注:ScannernextLine() APIを使用して、行全体を読み取ることもできます。

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()である一連の操作があり、整数を指定して改行を押すと入力として、両方の操作が実行されます。

nextInt() APIは整数を消費し、nextLine() APIは行区切り文字を消費し、Scannerを次の行の先頭に配置します。

6. 入力を検証

では、Scannerを使用して入力を検証する方法を見てみましょう。 次の例では、ScannerメソッドhasNextInt()を使用して、入力が整数値であるかどうかを確認します。

@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. Stringをスキャンします

次へ–Scannerを使用してStringをスキャンする方法を見てみましょう。

@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)は、次のトークンを16進整数値として読み取ります。

8. Patternを見つける

では、Scannerを使用してPatternを見つける方法を見てみましょう。

次の例では、入力全体で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();
}

次の例のように、findWithinHorizon()を使用して、特定のドメインでPatternを検索することもできます。

@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をスキップ

次へ–ScannerPatternをスキップする方法を見てみましょう。 Scannerを使用して入力を読み取るときに、特定のパターンに一致するトークンをスキップできます。

次の例では、Scannerメソッドskip()を使用して「Hello」トークンをスキップします。

@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を使用する複数の実際の例について説明しました。

Scannerを使用して、ファイル、コンソール、またはStringから入力を読み取る方法を学びました。また、Scannerを使用してパターンを見つけてスキップする方法、およびScanner区切り文字を変更する方法も学びました。

これらの例の実装はover on GitHubにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。