콘솔 입출력
콘솔이란? 콘솔(console) 은 환경에 따라 변경될 수 있다. 인텔리제이에서 실행했다면 인텔리제이의 콘솔 창이 콘솔이 될 것이고 윈도우 명령 창에서 프로그램을 실행했다면 명령 창이 콘솔이 된다. 즉, 콘솔은 사용자의 입력을 받거나 사용자에게 문자열을 출력해 주는 역할을 하는 것을 통칭하는 말이다.
인텔리제이 콘솔 창
콘솔 입력
생년월일을 입력하라는 질문
2002/01/01
자바에서 사용자가 입력한 문자열을 얻기 위해서는 다음과 같이 System.in을 사용한다.
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
int a;
a = in.read();
System.out.println(a);
}
}
여기서 작성한 InputStream은 자바의 내장 클래스이다. 이와 같이 java.lang 패키지에 속해 있지 않은 자바 내장 클래스는 필요할 때마다 임포트(import) 해서 사용해야 한다.
InputStream
InputStream은 바이트(byte) 단위의 데이터를 읽어 들일 때 사용하는 내장 클래스이다. 앞서 만든 프로그램을 실행해 이번엔 abc를 연속해서 입력한 후 Enter 키를 눌러 보자. a를 입력했을 때와 마찬가지로 97이 출력된다.
97
이렇게 사용자가 전달한 1byte의 데이터 또는 3byte의 데이터를 입력 스트림이라고 한다. 스트림(stream) 은 byte의 흐름을 추상화한 개념이며 데이터를 byte 단위로 다룬다.
그렇다면 사용자가 3byte를 입력했을 때 3byte를 전부 읽고 싶다면 어떻게 해야 할까? 다음처럼 코드를 수정해 보자.
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
int a;
int b;
int c;
a = in.read();
b = in.read();
c = in.read();
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
abc (입력 + 엔터)
97 (출력)
98 (출력)
99 (출력)
read 메서드를 3번 실행하도록 수정하고 프로그램을 다시 실행해 보자. 이번에는 abc를 입력하면 총 3byte를 읽어 들여 a, b, c 각각의 아스키코드값을 출력한다.
InputStreamReader
우리가 입력한 문잣값을 그대로 출력해 볼 수는 없을까? byte 대신 문자로 입력 스트림을 읽으려면 InputStreamReader를 사용하면 된다. 다음처럼 코드를 수정해 보자.
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
char[] a = new char[3];
reader.read(a);
System.out.println(a);
}
}
InputStreamReader를 사용하기 위해 import 문이 하나 더 추가되었다.
프로그램을 실행해 abc를 입력한 후 Enter 키를 눌러 사용자 입력을 전달해 보자. 그럼 다음과 같이 문자열 abc가 한꺼번에 출력되는 것을 확인할 수 있다.
abc (입력)
abc (출력)
BufferedReader
앞서 살펴본 예제에서는 3byte만 읽도록 고정되어 있었다. 길이에 상관없이 사용자가 입력한 값을 모두 받아들일 수는 없을까?
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
String a = br.readLine();
System.out.println(a);
}
}
BufferedReader를 이용하기 위해 import 문이 추가되었다. BufferedReader는 객체를 생성할 때 생성자의 입력으로 InputStreamReader의 객체가 필요하다. 이제 BufferedReader의 readLine 메서드를 이용하면 사용자가 입력한 문자열 전부를 읽을 수 있게 된다. 프로그램을 실행하고 "Hello World"를 입력한 후 Enter 키를 누르면 문자열 "Hello World"가 그대로 출력되는 것을 확인할 수 있다.
Hello World (입력)
Hello World (출력)
자바 입문자는 스트림을 처음 배울 때 대부분 혼란스러워 한다. 감싸고, 감싸고, 또 감싸니 도대체 내부적으로 어떻게 돌아가는지 헷갈릴 수밖에 없다. 다음과 같이 기억해 보자.
- InputStream: byte를 읽는다.
- InputStreamReader: character(문자)를 읽는다.
- BufferedReader: String(문자열)을 읽는다.
Scanner
J2SE 5.0부터 java.util.Scanner 클래스가 새로 추가되었다. Scanner 클래스를 이용하면 콘솔 입력을 보다 쉽게 처리할 수 있다. 다음 예를 살펴보자.
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(sc.next());
}
}
Scanner를 사용하기 위해서는 먼저 java.util.Scanner 클래스를 import해야 한다. Scanner 클래스는 생성자의 입력으로 System.in 객체가 필요한데, 이는 콘솔 입력인 InputStream이 필요하다는 의미이다.
- next: 토큰을 읽어 들일 수 있다.
- nextLine: 라인을 읽어 들일 수 있다.
- nextInt: 정수를 읽어 들일 수 있다.
콘솔 출력
우리는 System.out.println 메서드를 계속해서 사용해 왔다. System.out은 PrintStream 클래스의 객체이다. PrintStream은 콘솔에 값을 출력할 때 사용되는 클래스이다. 보통 System.out.println은 콘솔에 문자열을 출력할 때나 디버깅할 때 많이 사용한다. System.err도 있는데 System.out과 동일한 역할을 한다. 다만 System.err는 오류 메시지를 출력할 때 사용한다.
파일 입출력
파일 쓰기
import java.io.FileOutputStream;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
FileOutputStream output = new FileOutputStream("c:/out.txt");
output.close();
}
}
이 예제를 실행하면 c:/ 디렉터리 바로 밑에 새로운 파일인 out.txt가 생성되는 것을 확인할 수 있다.
FileOutputStream 클래스를 사용하면 이와 같이 파일을 생성할 수 있다. FileOutputStream 클래스는 객체를 생성할 때 생성자의 입력으로 파일명을 넘겨주어야 한다. 이 예제에서는 경로를 포함하여 c:/out.txt라는 파일명을 생성자의 입력으로 전달하였다.
output.close()라는 문장이 있는데 이것은 사용한 파일 객체를 닫아 주기 위한 코드이다. 사실 이 문장은 생략해도 된다. 왜냐하면 자바 프로그램을 종료할 때 사용한 파일 객체를 자동으로 닫아 주기 때문이다. 그럼에도 불구하고 직접 사용한 파일은 항상 닫아 주는 것이 좋다. 사용했던 파일을 닫지 않고 다시 사용하려고 할 경우에는 오류가 발생하기 때문이다.
FileOutputStream
import java.io.FileOutputStream;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
FileOutputStream output = new FileOutputStream("c:/out.txt");
for(int i=1; i<11; i++) {
String data = i+" 번째 줄입니다.\r\n";
output.write(data.getBytes());
}
output.close();
}
}
InputStream과 마찬가지로 OutputStream 역시 byte 단위로 데이터를 처리하는 클래스이다. 여기서 사용한 FileOutputStream은 OutputStream 클래스를 상속받아 만든 클래스이므로 역시 byte 단위로 데이터를 처리한다.
FileWriter
import java.io.FileWriter;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("c:/out.txt");
for(int i=1; i<11; i++) {
String data = i+" 번째 줄입니다.\r\n";
fw.write(data);
}
fw.close();
}
}
FileOutputStream 대신에 FileWriter를 이용하면 byte 배열 대신 문자열을 사용할 수 있어 편리하다.
PrintWriter
FileWriter를 사용하더라도 \r\n을 문자열 뒤에 덧붙여야 해 번거롭다. 이런 불편함을 해소하려면 FileWriter 대신 PrintWriter를 사용하면 된다. PrintWriter를 이용하면 \r\n을 덧붙이는 대신 println이라는 메서드를 사용할 수 있다.
import java.io.IOException;
import java.io.PrintWriter;
public class Sample {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter("c:/out.txt");
for(int i=1; i<11; i++) {
String data = i+" 번째 줄입니다.";
pw.println(data);
}
pw.close();
}
}
PrintWriter를 사용한 프로그램을 실행한 후, out.txt 파일에 어떤 내용이 저장되었는지 확인해 보자. System.out을 사용한 프로그램을 실행했을 때 콘솔에 출력될 내용이 파일에 고스란히 들어가 있는 것을 확인할 수 있다.
PrintWriter를 사용한 파일 출력 화면
System.out을 사용한 콘솔 출력 화면
파일에 내용 추가하기
프로그램을 만들다 보면 파일에 내용을 입력한 후 새로운 내용을 추가할 수도 있다. 이런 경우에는 이미 작성된 파일을 추가 모드로 열어서 추가할 내용을 작성하면 된다.
import java.io.FileWriter;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("c:/out.txt");
for(int i=1; i<11; i++) {
String data = i+" 번째 줄입니다.\r\n";
fw.write(data);
}
fw.close();
FileWriter fw2 = new FileWriter("c:/out.txt", true); // 파일을 추가 모드로 연다.
for(int i=11; i<21; i++) {
String data = i+" 번째 줄입니다.\r\n";
fw2.write(data);
}
fw2.close();
}
}
fw2 객체는 FileWriter("c:/out.txt", true)에서 알 수 있듯 두 번째 파라미터를 추가로 전달하여 생성했다.
파일 읽기
import java.io.FileInputStream;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
byte[] b = new byte[1024];
FileInputStream input = new FileInputStream("c:/out.txt");
input.read(b);
System.out.println(new String(b)); // byte 배열을 문자열로 변경하여 출력
input.close();
}
}
다만 byte 배열을 이용하여 파일을 읽어야 하기 때문에 읽어야 하는 데이터 길이를 모를 경우에는 좀 불편한 방법이다. 여기서는 1024byte를 읽도록 코딩했다.
파일을 한 줄(라인) 단위로 읽어 들일 수 있다면 훨씬 편리할 것이다. FileInputStream 대신 FileReader와 BufferedReader의 조합을 사용하면 한 줄 단위로 파일을 읽을 수 있다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Sample {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("c:/out.txt"));
while(true) {
String line = br.readLine();
if (line==null) break; // 더 이상 읽을 라인이 없을 경우 while 문을 빠져나간다.
System.out.println(line);
}
br.close();
}
}
BufferedReader의 readLine 메서드는 더 이상 읽을 라인이 없을 경우 null을 리턴한다.
객관식 문제
- Java에서 표준 출력에 사용되는 클래스는 무엇인가요? (정답:b)
- A) Scanner
- B) System
- C) BufferedReader
- D) InputStream
- System.out.println()에서 println의 역할은 무엇인가요? (정답:b)
- A) 파일을 읽는다.
- B) 화면에 내용을 출력한다.
- C) 텍스트를 입력받는다.
- D) 문자열을 객체로 변환한다.
- Java의 입출력 클래스 중 버퍼를 사용하여 효율적인 입출력을 제공하는 클래스는 무엇인가요? (정답:b)
- A) File
- B) BufferedReader
- C) Scanner
- D) System
- 파일에 텍스트를 쓰기 위해 가장 많이 사용되는 클래스는? (정답:b)
- A) FileReader
- B) FileWriter
- C) BufferedReader
- D) Scanner
- Java의 Scanner 클래스는 어떤 패키지에 속해 있나요? (정답:b)
- A) java.io
- B) java.util
- C) java.nio
- D) java.lang
- 다음 중 System.out.println()에서 out의 역할은 무엇인가요? (정답:b)
- A) 입력을 받아오는 스트림
- B) 표준 출력 스트림
- C) 파일을 읽는 스트림
- D) 네트워크 통신 스트림
- 파일에서 데이터를 읽어오는 대표적인 클래스는 무엇인가요? (정답:a)
- A) FileReader
- B) FileWriter
- C) Scanner
- D) PrintStream
- Java의 BufferedWriter 클래스는 어떤 기능을 제공하나요? (정답:d)
- A) 파일을 삭제한다.
- B) 파일을 읽는다.
- C) 파일을 압축한다.
- D) 텍스트를 버퍼에 쓰고 출력 성능을 향상시킨다.
- InputStream 클래스의 역할은 무엇인가요? (정답:b)
- A) 파일을 생성한다.
- B) 데이터를 입력받는다.
- C) 데이터를 네트워크로 전송한다.
- D) 데이터를 파일에 쓴다.
- FileReader와 FileWriter의 차이점은 무엇인가요? (정답:b)
- A) FileReader는 데이터를 파일에 쓰고, FileWriter는 파일을 읽는다.
- B) FileReader는 파일을 읽고, FileWriter는 데이터를 파일에 쓴다.
- C) FileReader는 문자열만 처리하고, FileWriter는 숫자만 처리한다.
- D) 두 클래스는 동일한 기능을 한다.
코딩테스트 문제
문제1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long A = sc.nextLong();
long B = sc.nextLong();
sc.close();
System.out.println(lcm(A, B));
}
public static long lcm(long a, long b) {
long max = Math.max(a, b);
for (long i = max; i <= a * b; i += max) {
if (i % a == 0 && i % b == 0) {
return i;
}
}
return a * b;
}
}
문제2
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int K = sc.nextInt();
int[] scores = new int[N];
for (int i = 0; i < N; i++) {
scores[i] = sc.nextInt();
}
sc.close();
Arrays.sort(scores);
System.out.println(scores[N - K]);
}
}
'WINK-(Web & App) > JAVA 스터디' 카테고리의 다른 글
[2024-2 Java 스터디] 김지나 #6주차 (0) | 2024.11.20 |
---|---|
Java[2024-2 Java 스터디] 이민형 #5주차 6장 (0) | 2024.11.14 |
[2024-2 Java 스터디] 김태일 #5주차 "자바의 입출력" (0) | 2024.11.14 |
[2024-2 Java 스터디] 강보경 #5주차 (0) | 2024.11.14 |
[2024-2 Java 스터디] 김지나 #5주차 "6장" (0) | 2024.11.14 |