웹사이트 검색

Java의 스캐너 클래스


Java 스캐너 클래스는 java.util 패키지의 일부입니다. Java 1.5 릴리스에서 도입되었습니다. 스캐너는 주로 사용자 입력을 수신하고 이를 int, double 또는 기본 문자열과 같은 기본 데이터 유형으로 구문 분석하는 데 사용됩니다. 토큰을 생성하여 정규 표현식을 사용하여 데이터를 구문 분석하는 유틸리티 클래스입니다.

Java 스캐너 클래스 생성자

Scanner 클래스를 보면 많은 생성자가 있습니다.

대부분의 생성자는 다음 세 개체 중 하나를 사용합니다.

  1. InputStream - 사용자 입력을 받기 위해 System.in을 전달하는 가장 일반적인 것입니다.
  2. 파일 또는 경로 - 파일 데이터도 스캔하고 파일의 값으로 작업할 수 있습니다.
  3. 문자열 - 문자열 소스에 대한 스캐너도 만들고 여기에서 값을 구문 분석할 수 있습니다.

두 번째 인수를 보면 파싱에 기본 문자 집합을 사용하지 않으려면 문자 집합을 지정하는 것입니다.

스캐너 클래스의 중요한 방법

가장 일반적으로 사용되는 Scanner 클래스 메서드 중 일부를 살펴보겠습니다.

  • useDelimiter(String pattern) - 스캐너에 사용할 구분 기호입니다. 기본 구분 기호는 공백입니다.
  • hasNext() - 입력에 다른 토큰이 있으면 true를 반환합니다. 차단 방법이며 사용자 입력을 계속 기다립니다.
  • next() - 스캐너에서 다음 토큰을 반환합니다. hasNext() 메서드와 함께 사용됩니다.
  • close() - 스캐너는 리소스가 많으므로 작업이 끝나면 이 메서드를 사용하여 스캐너를 닫고 시스템 리소스를 해제합니다.

int, short, long, byte, BigDecimal 등의 입력 토큰을 확인하고 직접 구문 분석하는 많은 유틸리티 메서드가 있습니다.

스캐너 초기화 및 사용 단계

  1. 첫 번째 단계는 InputStream, File 또는 String과 같은 입력 유형에 따라 적절한 생성자를 사용하여 스캐너 클래스를 초기화하는 것입니다. 필요한 경우 사용할 구분 기호 및 문자 집합을 설정합니다.
  2. 두 번째 단계는 hasNext() 메서드를 사용하여 입력 토큰을 기다리는 것입니다.
  3. 그런 다음 next() 메서드를 사용하여 토큰을 읽고 하나씩 처리합니다.

스캐너는 어떻게 작동합니까?

  • 스캐너 클래스는 지정된 구분 기호 패턴을 사용하여 입력을 토큰으로 나눕니다.
  • next() 메서드는 토큰을 하나씩 읽고 처리하는 데 사용됩니다.
  • 마지막으로 스캐너 인스턴스를 닫아 시스템 리소스를 해제합니다.

스캐너 예

샘플 코드 스니펫과 함께 Scanner 클래스의 일반적인 사용법 중 일부를 살펴보겠습니다.

1. 사용자 입력 읽기

이것이 Scanner 클래스의 가장 일반적인 용도입니다. System.in을 입력 소스로 인스턴스화하고 사용자 입력을 읽을 수 있습니다.

// read user input
Scanner sc = new Scanner(System.in);
System.out.println("Please enter your name");
String name = sc.next();
System.out.println("Hello " + name);
sc.close();

산출:

Please enter your name
Pankaj
Hello Pankaj

글쎄, 그것은 쉽고 잘 작동하는 것 같습니다. 그러나 위의 코드에는 문제가 있습니다. 다음 섹션을 읽지 않고 코드를 확인하고 식별할 수 있습니까?

입력에 내 전체 이름을 쓰면 어떻게 되는지 봅시다.

Please enter your name
Pankaj Kumar
Hello Pankaj

이제 이해하셨을 것입니다. 공백이 구분 기호이기 때문에 발생합니다. 스캐너는 입력을 Pankaj와 Kumar의 두 토큰으로 나눕니다. 그러나 우리는 next() 메서드를 한 번만 호출하므로 "Hello Pankaj\만 출력됩니다.

이 문제를 어떻게 해결합니까?

간단 해. useDelimiter() 메서드를 사용하여 구분 기호를 개행 문자로 변경할 수 있습니다.

Scanner sc = new Scanner(System.in);
sc.useDelimiter(System.getProperty("line.separator"));
System.out.println("Please enter your name");
String name = sc.next();
System.out.println("Hello " + name);
sc.close();

2. 스캐너를 사용한 파일 데이터 파싱

스캐너 클래스를 사용하여 CSV 파일을 읽고 구문 분석하는 간단한 예를 살펴보겠습니다. 다음 내용이 포함된 Employees.csv 파일이 있다고 가정해 보겠습니다.

1,Jane Doe,CEO
2,Mary Ann,CTO
3,John Lee,CFO

파일을 읽고 Java 프로그램에서 직원 목록을 가져옵니다.

package com.journaldev.java;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ScannerExamples {

	public static void main(String[] args) throws IOException {

		// create scanner for the CSV file
		Scanner sc = new Scanner(new File("employees.csv"));

		// set delimiter as new line to read one line as a single token
		sc.useDelimiter(System.getProperty("line.separator"));

		// create the List of Employees
		List<Employee> emps = new ArrayList<>();

		while (sc.hasNext()) {
			Employee emp = parseEmployeeData(sc.next());
			emps.add(emp);
		}

		// close the scanner
		sc.close();

		// print employee records
		System.out.println(emps);
	}

	private static Employee parseEmployeeData(String record) {
		// create scanner for the String record
		Scanner sc = new Scanner(record);

		// set delimiter as comma
		sc.useDelimiter(",");

		Employee emp = new Employee();
		emp.setId(sc.nextInt());
		emp.setName(sc.next());
		emp.setRole(sc.next());

		// close the scanner
		sc.close();

		return emp;
	}

}

class Employee {
	private int id;
	private String name;
	private String role;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	@Override
	public String toString() {
		return "Emp[" + id + "," + name + "," + role + "]";
	}
}

  • 첫 번째 단계는 CSV 파일용 스캐너를 만들고 개행을 구분 기호로 설정하는 것입니다.
  • 그런 다음 CSV 형식의 직원 레코드가 포함된 각 줄에 대해 다른 스캐너와 쉼표를 구분 기호로 사용하여 구문 분석합니다. parseEmployeeData()는 각 행을 구문 분석하고 Employee 객체를 생성합니다.
  • 마지막으로 직원 개체를 목록에 추가하고 인쇄합니다.

출력: [Emp[1,Jane Doe,CEO], Emp[2,Mary Ann,CTO], Emp[3,John Lee,CFO]]

3. 자바 스캐너 정규식 예제

문자열 소스가 있고 그 안에 있는 정수만 처리하려고 한다고 가정해 보겠습니다. 숫자가 아닌 정규식과 함께 스캐너를 사용하여 처리할 토큰으로 정수만 가져올 수 있습니다.

//using regex to read only integers from a string source
String data = "1a2b345c67d8,9#10";
Scanner sc1 = new Scanner(data);

// setting non-digit regex as delimiter
sc1.useDelimiter("\\D");

while(sc1.hasNext()) {
	System.out.println(sc1.next());
}

// don't forget to close the scanner
sc1.close();

산출:

1
2
345
67
8
9
10

결론

Java 스캐너는 사용자 입력을 읽거나 파일 또는 문자열 소스의 간단한 정규식 기반 구문 분석을 처리하는 유틸리티 클래스입니다. 그러나 실제 응용 프로그램의 경우 성능 향상을 위해 Scanner 클래스를 사용하는 것보다 CSV 파서를 사용하여 CSV 데이터를 구문 분석하는 것이 좋습니다.

참조: Java의 정규식