[자바] 입출력 - BufferedReader, Scanner, BufferedWriter, Stringbuilder

강은서·2022년 1월 29일
0

Java

목록 보기
6/9
post-thumbnail

입력

스캐너

Scanner sc = new Scanner(System.in);
  • 정수값으로 int, short, long 소수 값으로 float, double를 구분지어 읽어들일 수 있고, String 값도 읽을 수 있다.
  • int, long, short 의 경우 nextInt(), nextLong(), nextShort()과 같이 정규식을 사용하여 값을 파싱한다.

BufferedReader

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine(); //입력 받을 값이 String일 때
int a = br.read();			//입력 받을 값이 int형 일때
int b = Integer.parseInt(br.readLine());	//int값 + 엔터까지 입력받을 때
  • 한 줄을 통째로 받는 방식이다.
  • 오직 문자열 값만을 읽기 때문에 readLine() 함수만을 사용한다.
    - 예외 처리를 방드시 필요로 한다. readLine()시 마다 try/catch문으로 감싸주어도 되고, throws IOException을 통한 예외처리를 해도 된다.

Scanner와 BufferedReader의 차이

- BufferedReader은 Scanner에 비해 상당히 큰 버퍼를 차지한다.
Scanner의 경우 1KB, BufferedReader의 경우 8KB를 차지해 긴 문자열이 포함된 파일을 읽을 시에는 BufferedReader를 추천하지만 내용이 짧은 경우 Scanner를 사용하는 것이 좋다.

- BufferedReader의 경우, 동기화를 사용하지만 Scanner는 사용하지 않는다.
여러 스레드간에 Scanner를 공유할 수 없지만, BufferedReader 개체는 공유할 수 있다. 동기화를 사용하는 BufferedReader의 경우 single thread를 사용하는 Scanner보다 약간 느리지만, Scanner는 정규식을 사용하여 값을 받으므로 이러한 속도 차이는 보상을 넘어 BufferedReader가 더 빠르게 문자열을 읽을 수 있게 된다.

데이터 가공

BufferedReader를 통해 읽어 온 데이터는 개행문자 단위(Line단위)로 나누어지며 이를 공백단위로 데이터를 가공하고자 하면 StringTokenizer나 String.split()함수를 사용하여 따로 작업을 해줘야 한다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

String arr[] = s.split(" ");
  • StringTokenzier
    - nextToken() 함수를 사용하면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
  • String.split()
    - 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.

출력

BufferedWriter

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

String str = "abcdef";
bw.write(str); //출력
bw.newLine(); //줄바꿈
bw.flush();  //남아있는 데이터 모두 출력
bw.close();

String과 StringBuffer/StringBuilder의 차이

String은 불변 속성을 갖고, StringBuffer/StringBuilder는 그렇지 않다.

  • 불변성을 갖는다

    concat이나 + 연산을 통해 값을 변경하려면, 원래 기존의 String메모리에서 값이 바뀌는 것이 아니라 기존의 String에 들어있던 값을 버리고 새로운 값을 재할당하게 된다. 처음에 할당한 String의 메모리 영역은 Garbage로 남아있다가 GarbageCollection에 의해 없어진다.

    String은 불변성을 가지기 때문에 문자열을 자주 읽어들이는 경우 사용하면 유리하다. 하지만 문자열 추가, 삭제, 수정 등의 연산이 자주 일어나는 경우에 String을 사용하면, 힙 메모리에 많은 Garbage가 생성되고 이는 힙 메모리 부족으로 이어져 프로그램의 성능에 치명적 영향을 미칠 수 있다.

  • 가변성을 갖는다.

    StringBuffer/StringBuilder는 가변성을 가지기 때문에, append(), delete()등 동일 객체 내에서 문자열을 변경하는 것이 가능하다.

StringBuffer과 StringBuilder의 차이

  • StringBuffer 동기화를 지원하여 멀티 쓰레드 환경에서 안전하다.
  • StringBuilder 동기화를 지원하지 않아 멀티 쓰레드 환경에 사용하기 적합하지 않다. 대신, 동기화를 지원하지 않기에 단일 쓰레드에서는 StringBuffer보다 성능이 뛰어나다.

(쓰레드, 동기화 등에 대해서는 아직 개념이 잡혀있지 않으니 추후에 다시 확인해야 한다.)

StringBuilder

StringBuilder sb = new StringBuilder();
sb.append("abc");
sb.append(1).append("/n");
System.out.println(sb); //쌓아둔 문장들을 한 번에 출력한다.
  • 출력하고 싶은 문장을 System.out.println을 이용하여 항상 출력하지 않고 builder에 쌓아둔다.
  • 한줄에 줄바꿈 기호까지 넣을 수 있다.

0개의 댓글