Java скенер

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.