하위 태스크 1
콘솔 입력 예제 작성
키보드 입력 → 콘솔 출력
다음은 사용자 입력을 콘솔에 그대로 출력하는 예제다.
import java.util.Scanner;
public class Echo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("입력: ");
String line = sc.nextLine();
if (line.isEmpty()) {
break;
}
System.out.println("출력: " + line);
}
sc.close();
}
}하위 태스크 2
바이트/문자 스트림 비교
두 방식으로 같은 기능 구현
바이트 스트림은 바이트 단위로 입력을 처리하고, 문자 스트림은 문자 단위로 입력을 처리한다.
특히 유니코드 문자를 처리할 때 차이점이 두드러진다. IntelliJ 콘솔은 사용자 입력을 UTF-8로 인코딩한다. UTF-8 인코딩은 ASCII 문자를 1바이트로, 한글을 3바이트로 인코딩한다. 바이트 스트림으로 하나의 한글 문자를 읽으면 3바이트 중 첫 바이트만 읽어들여 불완전한 코드 포인트를 얻는다. 문자 스트림으로 하나의 한글 문자를 읽으면 3바이트 전체를 읽어들여 완전한 코드 포인트를 얻는다.
다음 예제는 바이트 스트림(InputStream)과 문자 스트림(InputStreamReader)을 사용해서 입력한 문자의 코드 포인트를 얻는다. 같은 문자를 입력 받아도 다른 코드 포인트를 출력한다.
public class Streams {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
// 바이트 스트림
System.out.println(in.read()); // 입력: 가, 출력: 234
// 버퍼 비우기
while (in.available() > 0) {
in.read();
}
// 문자 스트림
InputStreamReader reader = new InputStreamReader(in);
System.out.println(reader.read()); // 입력: 가, 출력: 44032
}
}하위 태스크 3 ~ 6
파일 읽기 로직 구현
파일을 줄 단위로 읽기
필터링 로직 구현
특정 단어 포함 줄만 골라 출력
try-with-resources 적용
스트림 자동 close 코드로 개선
예외 처리 강화
파일 없음/인코딩 문제 등 처리
로그 내역이 기록된 입력 파일 logs.txt는 다음과 같다.
[INFO] 애플리케이션이 정상적으로 시작되었습니다
[WARNING] 메모리 사용량이 80%를 초과했습니다
[DANGER] 데이터베이스 연결이 끊어졌습니다
[WARNING] API 응답 시간이 평소보다 느립니다
[DANGER] 디스크 공간이 부족합니다 (5% 남음)
[INFO] 사용자 로그인이 완료되었습니다
다음 예제는 파일 입출력 클래스를 사용해 입력 파일을 분석하고, 특정 태그가 포함된 로그만을 콘솔에 출력한다.
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class FileUsage {
public static boolean hasCorruptedChar(String line) {
return line.contains("\uFFFD");
}
public static void main(String[] args) {
try (Scanner sc = new Scanner(System.in)) {
System.out.print("파일 경로: ");
String path = sc.nextLine();
try (BufferedReader br = new BufferedReader(new FileReader(path, StandardCharsets.UTF_8))) {
while (true) {
String line = br.readLine();
if (line == null) {
break;
}
if (line.contains("[INFO]")) {
System.out.println(line);
}
if (hasCorruptedChar(line)) {
System.err.println("경고! 파일 인코딩에 문제가 존재할 수 있습니다.");
}
}
} catch (FileNotFoundException e) {
System.err.println("파일을 찾을 수 없습니다.");
} catch (IOException e) {
System.err.println("파일을 읽을 수 없습니다.");
}
}
}
}