안녕하세요. J4J입니다.
이번 포스팅은 자바의 입/출력에 대해 적어보는 시간을 가져보려고 합니다.
프로그래밍을 위해 IDE를 사용하면서 입/출력을 수행하고 싶을 때 어떠한 지시가 없으면 IDE는 스스로 입/출력과 관련된 기능을 수행하지 않습니다.
그리고 프로그래밍 언어마다 입/출력하는 방식이 다르기 때문에 각각의 언어에 맞는 입/출력 방식을 사용하여 지시를 내려줘야 되고 자바에서 입/출력에 대한 지시를 내릴 수 있는 방법은 한 가지만 있는 것이 아닙니다.
저는 그 중에서 입력과 출력 모두 각각 2가지 방법을 소개하고자 합니다.
먼저 출력부터 보도록 하겠습니다.
출력 1: System.out
자바에서 출력을 받을 수 있는 방법 중 첫 번째는 System.out입니다.
System.out은 자바 출력의 대부분을 차지한다고 생각해도 될 정도입니다.
System.out에서는 사용할 수 있는 메서드가 2개가 있습니다.
- print(x): x값을 출력만 함
- println(x): x값을 출력하고 개행 시킴 (다음 줄로 넘어감)
사용방법은 다음 코드와 같습니다.
package input_output;
public class Output1 {
public static void main(String[] args) {
System.out.print("안녕하세요.");
System.out.print("저는 J4J입니다.");
System.out.println("안녕하세요.");
System.out.println("저는 J4J입니다.");
}
}
위의 실행 결과와 같이 print()는 개행을 하지 않고 출력만 하게 되어 두 번째 안녕하세요까지 같은 줄에 출력되는 것을 볼 수 있습니다.
두 번째 안녕하세요는 print()가 아니라 println()으로 작성되었기 때문에 개행이 되는 것을 볼 수 있습니다.
출력 2: BufferedWriter
자바에서 출력할 수 있는 두 번째 방법은 BufferedWriter입니다.
BufferedWriter를 사용하여 출력하는 방법은 한 가지밖에 없습니다.
사용방법은 다음 코드와 같습니다.
package input_output;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Output2 {
public static void main(String[] args) throws IOException { // 예외처리 필수
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("출력에 대해 ");
bw.write("설명하고 있어요.");
bw.flush();
bw.write("출력에 대해 \n");
bw.write("설명하고 있어요.");
bw.flush();
}
}
위와 같이 BufferedWriter 객체를 생성한 뒤 write(x)를 사용하여 출력을 합니다.
하지만 BufferedWriter의 특징은 write(x)가 실행된다고 바로 출력이 되지 않습니다.
write(x)를 통해 출력할 값을 버퍼에 저장시켰다가 flush()를 통해 버퍼에 저장되어 있던 값들을 출력시켜 줍니다.
또한 write()같은 경우는 위의 System.out.print()와 동일하게 개행이 되지 않기 때문에 개행 문자인 \n을 넣어줌으로 써 개행시켜줄 수 있습니다.
그럼 여기서 System.out이 BufferedWriter보다 더 사용하기 편해보이는데 BufferedWriter를 왜 사용하는지에 대한 의문이 생길 것입니다.
그 이유는 BufferedWriter가 대량의 데이터들을 출력해줄 때 속도가 더 빠릅니다.
하지만 크게 차이나지 않기 때문에 대부분의 사람들이 System.out을 사용합니다.
특정 상황이 아니면 둘 중 고민하지 말고 System.out 사용을 추천드립니다.
입력 1: Scanner
자바에 입력을 받을 수 있는 방법 중 첫 번째는 가장 흔하게 사용되는 Scanner를 이용하는 방법입니다.
다음은 Scanner를 이용하여 사용할 수 있는 메서드들 중 일부입니다.
- nextInt(): int형에 해당하는 값을 입력 받음
- nextBoolean(): boolean형에 해당하는 값을 입력 받음
- next(): 문자열에 해당하는 값을 입력 받음 (공백을 기준으로 문자열을 입력 받음)
- nextLine(): 문자열에 해당하는 값을 입력 받음 (한 줄을 기준으로 문자열을 입력 받음)
사용방법은 다음 코드와 같습니다.
package input_output;
import java.util.Scanner;
public class Input1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextInt()); // int형
System.out.println(scanner.nextBoolean()); // boolean형
System.out.println(scanner.next()); // 문자열
System.out.println(scanner.nextLine()); // 문자열
scanner.close();
}
}
10, true, J4J Tistory를 차례대로 입력할 경우 위와 같은 실행결과가 나옵니다.
왜 이렇게 나올까요?
nextInt()에서 10을 받고 nextBoolean()에서 true를 입력받습니다.
그리고 next()에서 J4J Tistory를 모두 입력받지 않고 공백을 기준으로 입력받는 next()의 특징에 따라 J4J만 입력받습니다.
next()에서 입력받은 J4J를 제외한 Tistory는 nextLine()에서 입력받는 결과를 만들어줍니다.
그럼 위의 코드에 next()를 하나 더 추가해보도록 하겠습니다.
package input_output;
import java.util.Scanner;
public class Input1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextInt()); // int형
System.out.println(scanner.nextBoolean()); // boolean형
System.out.println(scanner.next()); // 문자열
System.out.println(scanner.next()); // 문자열
System.out.println(scanner.nextLine()); // 문자열
scanner.close();
}
}
다시 한번 10, true, J4J Tistory를 입력할 경우 위와 같은 실행결과가 나옵니다.
10과 true는 정상적이고 next()가 두 개이기 때문에 각각 J4J와 Tistory를 입력받습니다.
정상 동작한 것 같죠?
이에 대한 대답은 No입니다.
왜냐하면 nextLine()에 어떠한 값도 입력하지 않았는데 프로그램은 종료가 되었습니다.
그럼 프로그램이 왜 종료가 되었을까요?
그 이유는 nextLine()이 입력된 문자열의 마지막에 존재하는 개행 문자를 입력으로 받았기 때문입니다.
요약을 하자면 next()뿐만 아니라 nextInt(), nextBoolean() 등은 모두 마지막에 존재하는 개행 문자를 입력으로 받지 않기 때문에 바로 뒤에 nextLine()이 있을 경우 nextLine()은 개행문자를 받게 됩니다.
결국 nextLine()으로 또 다른 입력을 받고 싶으면 nextLine()을 한번 더 작성해야 된다는 뜻입니다.
그럼 nextLine() 뒤에 nextLine()이 있으면 어떨까요?
package input_output;
import java.util.Scanner;
public class Input1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine()); // 문자열
System.out.println(scanner.nextLine()); // 문자열
scanner.close();
}
}
nextLine()은 한 줄 전체, 즉 개행 문자까지 입력으로 받기 때문에 문제없이 두 문자열을 모두 입력으로 받을 수 있습니다.
이와 같이 Scanner를 사용할 때는 nextLine()의 개행 문자처리를 유의하여 사용한다면 문제없이 입력 처리를 수행할 수 있습니다.
입력 2: BufferedReader
다음 입력 방식은 BufferdReader입니다.
저는 입력방식을 사용할 때 Scanner대신에 BufferedReader만 사용을 하고 있습니다.
왜냐하면 출력방식에서 얘기했던 것처럼 대량의 데이터를 입력받을 때 BufferedReader가 Scanner보다 속도가 더 빠르기 때문입니다.
그리고 개인적으로 출력과 달리 Scanner보다 BufferedReader가 사용하기 더 편하게 느껴지기도 합니다.
BufferedReader는 Scanner와 다르게 int, boolean, double 등을 구분하지 않고 모두 한 줄의 문자열을 받아옵니다. (Scanner의 nextLine()처럼)
사용방법은 다음 코드와 같습니다.
package input_output;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Input2 {
public static void main(String[] args) throws IOException { // 예외처리 필수
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(br.readLine()); // 문자열
System.out.println(br.readLine()); // 문자열
}
}
이와 같이 BufferedReader 객체를 생성한 뒤 readLine()을 사용하여 문자열을 입력으로 받습니다.
그리고 모두 문자열로만 받기 때문에 Scanner에서 발생할 수 있었던 개행 문자를 읽어버리는 사고가 일어나지 않게 됩니다.
BufferedReader가 더 좋아 보이죠?
사실 Scanner와 BufferedReader 중 어떤 걸 사용해도 상관은 없습니다.
BufferedReader가 Scanner보다 속도가 더 빠르다는 것도 위의 출력방식과 동일하게 사실 크게 차이 나지 않거든요.
그렇기 때문에 더 손에 익숙해지는 방식을 선택해서 사용하시면 될 것 같습니다.
이상으로 입/출력에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Language > Java' 카테고리의 다른 글
[Java] 자바기초 - Wrapper Class (0) | 2020.12.13 |
---|---|
[Java] 자바기초 - 형 변환(Promotion/Casting) (0) | 2020.12.11 |
[Java] 자바기초 - 자료형 (2) | 2020.12.10 |
[Java] 자바기초 - IDE (0) | 2020.12.06 |
[Java] 자바기초 - JVM/JDK/JRE (0) | 2020.12.06 |
댓글