1. Преглед на скенера
В този бърз урок ще илюстрираме как да използваме класа Java Scanner - за четене на въвеждане, намиране и пропускане на модели с различни разделители.
2. Сканирайте файл
Първо - да видим как да четем файл с помощта на скенер .
В следния пример - четем файл, съдържащ „ 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(); }
Имайте предвид, че методът next () връща следващия String token тук.
Освен това обърнете внимание как затваряме скенера, когато приключим с използването му.
3. Преобразувайте InputStream в String
След това - нека видим как да конвертирате InputStream в низ с помощта на скенер :
@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“ - който съответства на пълния вход.
4. Скенер срещу BufferedReader
Сега - нека обсъдим разликата между Scanner и BufferedReader - обикновено използваме:
- BufferedReader, когато искаме да прочетем въведеното в редове
- Скенер за четене на въведените данни в маркери
В следния пример - четем файл в редове с помощта на 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(); }
Обърнете внимание как използваме API на Scanner nextLine () - за да прочетем целия ред .
5. Сканирайте входа от конзолата с помощта на нов скенер (System.in)
След това - нека видим как да четем въведените данни от конзолата с помощта на екземпляр на скенер :
@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. API на nextLine ()
Този метод просто връща низа в текущия ред:
scanner.nextLine();
Това чете съдържанието на текущия ред и го връща с изключение на всеки разделител на редове в края - в този случай - новия символ на реда.
След като прочете съдържанието, Scanner задава своята позиция в началото на следващия ред. Важният момент, който трябва да запомните, е, че API nextLine () консумира разделителя на редове и премества позицията на скенера към следващия ред .
Така че следващия път, ако четем през Scanner , ще четем от началото на следващия ред.
5.2. API на nextInt ()
Този метод сканира следващия маркер на входа като int:
scanner.nextInt();
API чете целочисления маркер, наличен по-нататък.
В този случай, ако следващият маркер е цяло число и след цялото число има разделител на редове, винаги помнете, че nextInt () няма да консумира разделителя на редове. Вместо това позицията на скенера ще бъде самият разделител на редове .
Така че, ако имаме поредица от операции, където първата операция е scanner.nextInt () и след това scanner.nextLine () и като вход, ако осигурим цяло число и прекъсване на реда, и двете операции ще бъдат изпълнени.
В nextInt () API ще консумира цялото число и nextLine () API ще консумира сепаратор линия и ще постави скенер за започване на следващия ред.
6. Проверка на въведеното
Сега - нека видим как да проверим въвеждането с помощта на скенер . В следния пример - използваме метода на 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. Сканирайте низ
След това - нека видим как да сканираме низ с помощта на скенер :
@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. Намерете модел
Сега - нека видим как да намерим шаблон с помощта на скенер .
В следния пример - използваме findInLine (), за да търсим маркер, който съответства на дадения модел в целия вход:
@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.
Научихме как да четем входни данни от файл, конзола или низ чрез скенер ; научихме също как да намерим и пропуснем шаблон с помощта на скенер - както и как да сменим разделителя на скенера .
Изпълнението на тези примери може да бъде намерено в GitHub.