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上找到。