Java Scanner简介

331 阅读4分钟
原文链接: www.ripjava.com

1.概述

在本教程中,我们将说明如何使用Java Scanner读取输入并查找和跳过具有不同分隔符的特定模式的字符串。

2.扫描文件

首先, 让我们看看如何使用Scanner读取文件。

在下面的示例中 - 我们使用Scanner将包含“ Hello world ” 的文件读入:

text.txt文件

 Hello world

测试代码

    @Test
    public void  test_ReadFileWithScanner() throws FileNotFoundException {
        System.out.println(new File(".").getAbsolutePath());
        Scanner scanner = new Scanner(new File("src/test/resources/text.txt"));
        assertThat(scanner.hasNext(), is(true));
        assertThat("Hello", is(scanner.next()));
        assertThat("world", is(scanner.next()));
        scanner.close();
    }

注意:Scanner方法*next()*返回下一个字符串。

3.将InputStream转换为String

接下来 ,让我们看看如何使用Scanner将InputStream转换为String:

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

注意:在上面的代码中,我们故意设置分隔符为“A”, 这样可以指直接在next()方法中获取完整的Hello world

4. Scanner与BufferedReader

现在,让我们讨论Scanner和BufferedReader之间的区别

  • 当我们想要将按行读取输入行时,使用BufferedReader
  • 当我们想要按照分隔符读取时,使用Scanner

我们分别来测试一下

我们使用BufferedReader将文件读入行:

text2.txt文件内容

Hello world
Hi, John

测试代码

    @Test
    public void test_ReadUsingBufferedReader()  throws IOException {
        String firstLine = "Hello world";
        String secondLine = "Hi, John";
        BufferedReader reader = new BufferedReader(new FileReader("src/test/resources/text2.txt"));

        String result = reader.readLine();
        assertEquals(firstLine, result);

        result = reader.readLine();
        assertEquals(secondLine, result);

        reader.close();
    }

让我们使用Scanner按照分隔符来读取:

    @Test
    public void test_ReadUsingScanner() throws IOException {
        String firstLine = "Hello world";
        FileInputStream inputStream = new FileInputStream("src/test/resources/text2.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();
    }

注意:在Scanner的测试代码里我们也用 nextLine() API来读取整行了。

5.使用Scanner从控制台获取输入

接下来,让我们看看如何使用Scanner从控制台读取输入:

    @Test
    public void test_ReadingInputFromConsole() {
        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使用行分隔符并将扫描的位置移动到下一行。 下次如果我们通过Scanner阅读,我们将从下一行的开头读取。

5.2 nextInt() API

此方法将输入的下一个扫描标记为int:

scanner.nextInt();

这将读取下一个可用的整数。

如果下一个标记是整数并且在整数之后有一个行分隔符,请始终记住nextInt() 不会读取行分隔符。Scanner的位置会是行分隔符本身。

6.验证输入

让我们看看如何使用Scanner验证输入。 在下面的示例中 - 我们使用Scanner方法hasNextInt()来检查输入是否为整数值:

    @Test
    public void test_ValidateInputUsingScanner() 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.扫描字符串

接下来, 让我们看看如何使用Scanner扫描字符串:

    @Test
    public void test_ScanString() 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. 查找特定模式的字符串

现在, 让我们看看如何使用Scanner找到一个特定模式的字符串。

在下面的示例中, 我们使用findInLine()来搜索与整个输入中给定模式匹配的标记:

    @Test
    public void test_FindPatternUsingScanner() throws IOException {
        String expectedValue = "world";
        FileInputStream inputStream = new FileInputStream("src/test/resources/text.txt");
        Scanner scanner = new Scanner(inputStream);

        String result = scanner.findInLine("wo..d");
        assertEquals(expectedValue, result);

        scanner.close();
    }

我们还可以使用findWithinHorizon()在特定的范围中搜索Pattern,如下例所示:

    @Test
    public void test_FindPatternInHorizon() throws IOException {
        String expectedValue = "world";
        FileInputStream inputStream = new FileInputStream("src/test/resources/text.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();
    }

注意,搜索范围只是执行搜索的字符数

9.跳过特定模式的字符串

我们可以在使用Scanner读取输入时跳过与特定模式匹配的标记。

在以下示例中 - 我们使用Scanner方法skip()跳过“ Hello ”:

    @Test
    public void test_SkipPatternUsingScanner() throws IOException {
        FileInputStream inputStream = new FileInputStream("src/test/resources/text.txt");
        Scanner scanner = new Scanner(inputStream);

        scanner.skip(".e.lo");

        assertEquals("world", scanner.next());

        scanner.close();
    }

10.更改Scanner分隔符

最后 - 让我们看看如何更改Scanner分隔符。 在以下示例中 - 我们将默认的Scanner分隔符更改为“ o ”:

    @Test
    public void test_ChangeScannerDelimiter() throws IOException {
        String expectedValue = "Hello world";
        String[] splited = expectedValue.split("o");

        FileInputStream inputStream = new FileInputStream("src/test/resources/text.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 test_ReadWithScannerTwoDelimiters()
            throws IOException {
        Scanner scanner = new Scanner(new File("src/test/resources/names.txt"));
        scanner.useDelimiter(",|-");

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

        scanner.close();
    }

注意:默认的分隔符是空格。

11.结论

在本教程中,我们讨论了使用Java Scanner的多个实际示例。

我们学习了如何使用Scanner从文件,控制台或字符串中读取输入;

我们还学习了如何使用Scanner*查找和跳过特定模式的字符串, 以及如何更改分隔符。

最后,往常一样,代码可以在Github上找到。