[JAVA] 입출력 BufferedReader/ BufferedWriter

윤재열·2023년 2월 20일
0

Java

목록 보기
68/71
post-custom-banner

알고리즘 공부를 하면 Scanner를 사용하는 일이 많은데,
많은 이들이 BufferedReader 와 BufferedWriter 를 사용하면서 알고리즘 측면에서 더 효율 높다는 것을 발견하였습니다.
초기 System.out.println() 할 데이터의 양이 적다면 큰 차이는 나지 않다고는 하지만, 데이터의 양이 컺리수록 Scanner와 BufferedReader / BufferedWriter의 차이는 더 크다고 합니다.

BufferedReader / BufferedWriter

  • Reader, Writer 라는 이름에서 알 수 있겠지만 입출력을 당당하고 있습니다.
  • 버퍼를 통해서 입출력을 전달합니다.

그렇다면 위에서 말한 BufferedReader / BufferedWriter이 Scanner 보다 효율이 좋다고 하는데 그 이유는 바로 버퍼를 이용해서 그렇습니다.

  • 버퍼는 우리가 키보드에 입력할때마다 값을 전달하는 것이 아니라 버퍼에 정해진 용량만큼 모아놓은 후에 전달을 해줍니다.

  • 그림만 보면 이해가 안되겠지만 쉽게 생각해보면
    택배 배송을 하는데 하나씩 옮기는 것보다 한꺼번에 옮기는 것이 더 효율적이다! 라고 이해하면됩니다.

  • 출력도 마찬가지로 버퍼를 통해서 프로그램에 전달이 되기 때문에 시스템의 데이터처리 효율성을 높여줄 수 밖에 없습니다.

    • 버퍼를 사용할 때, inputStream과 OutputStream 을 사용하는 이유가 입출력스트림 으로부터 미리 버퍼에 데이터를 담아주기 때문에 Scanner보다 효율적인 출력이 가능한 것입니다.

Buffer(버퍼) 란 ?

  • 데이터를 한곳에서 다른 한곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 임시 메모리 영역
  • 입출력 속도 향상을 위해 버퍼를 사용
  • 버퍼 플러시(buffer flush) : 버퍼에 남아있는데이터를 출력시킵니다(버퍼를 비우는 행위)
  • BufferedReader : 버퍼를 이용한 입력
  • BufferedWriter : 버퍼를 이용한 출력

BufferedReader

  • Scanner 로 입력을 할 경우에는 SpaceEnter를 경계로 인식하여 입력한 데이터를 가공하기가 매우 쉽습니다.
  • 하지만 BuffredReader 는 Enter로만 인식하고 return 된는 데이터가 String으로 고정되기 때문에 이를 int로 사용하기위해서는 약간의 변형을 줘야합니다.

  • 해당 코드가 BufferedReader 의 가장 기본적인 예제라고 볼 수 있습니다.
  • 입력하는 값이기 때문에 BufferedReader를 설정해주는데 여기에 InputStreamReader로 같이해줍니다.
  • 코드를 보면 readLine()이 있는데 이는 Scanner의 NextLine()의 역할을 하는것이라고 볼 수 있습니다.
  • 또한 BuffredReader는 return값이 String으로 고정되기 때문에 int 타입으로 변형시켜 주려면 Integer.parseInt()를 해줘야합니다.

해당 코드는 값 1개를 입력 할 수 있는데, 만약 여러개의 코드를 입력해야 한다면 어떻게 해야할까?

이럴때는 StringTokenizer 클래스를 이용하여 split을 통해 공백을 나눠줘서 작업을 해야합니다.

  • readLine() 메서드가 있기 때문에 Scanner 처럼 1과 2를 따로 입력하는것이 아니라 1 2 처럼 한줄에 입력을 해줘야 합니다.
  • 1 2 로 입력을 했다면 " "로 된 공백을 포함하여 버퍼에 넣어주게 되고, 이 공백을 나누기 위해서는 StringTokenizer와 Split을 통해 입력한 값을 나눠줍니다.

  • 이와 같이 delim(delimit)을 사용하여 나타낼 수도 있습니다.

BuffredWriter

  • 흔히 알고 있는 System.out.println() 과 동일 기능을 하는 메서드입니다.
  • 이것 또한 버퍼를 이용하기 때문에 효율이 좋고 많은 양의 데이터를 처리할 때 유용합니다.

  • BufferdReader와 BuffredWriter를 사용한 예제입니다.
  • 해당 메서드를 사용할 때는 bw.write() 처럼 이것을 사용한다고해서 바로 출력되는 것이 아닙니다.
  • Scanner 처럼 바로 적용되는 것이아니라 버퍼에 데이터를 저장했다가 버퍼가 flush 나 close가 될때 한번에 Stream 쪽으로 전달이 되기 때문입니다.
  • 따라서 해당값을 출력하기 위해서는 bw.flush() 와 bw.close()를 꼭 사용해주어야합니다.
  • 만약 계쏙 사용해주고 싶다면 bw.close() 는 완전히 기능을 닫아버리기 때문에 계속하기 위해서는 bw.flush()를 사용해주어야합니다.
    • 만약 줄바꿈이 필요하다면 newLine()을 이용해줍니다.
  • 또한 write() 메서드는 String으로만 출력이 가능해서 정수값으로 출력하려면 String.valueOf()를 통해 타입을 변환해주어야 합니다.
  • 이 메서드는 버펄르 잡아두기 때문에 flush()와 close()를 통하여 처리해 주어야하며, System.out.println() 처럼 자동적으로 개행처리가 안되기 때문에 newLine()이나 \n을 통해 개행처리를 해주는 것이 좋습니다.

메서드 종류와 기능

  • BufferedReader(Reader rd) : rd에 연결되는 문자입력 버퍼스트림 생성
  • BufferedWriter(Writer wt) : wt에 연결되는 문자 출력 버퍼스트림 생성
  • int read() : 스트림으로부터 한 문자를 읽어서 int형으로 리턴
  • int read(char[] buf) : 문자배열 buf의 크기만큼 문자를 읽어들입니다.(읽어들인 문자수를 return)
  • int read(char[] buf, int offset, int length) : buf의 offset 위치에서부터 length길이만큼 문자를 스트림으로부터 읽어들임
  • String readLine() : 스트림으로부터 한 줄을 읽어 문자열로 return 해줍니다.
  • void mark() : 현재위치를 마킹, 차후 reset() 을 이용하여 마킹위치로부터 시작
  • void reset() : 마킹이 있으면 그 위치에서부터 다시 시작, 그렇지 않다면 처음부터 다시시작
  • long skip(int n) : n개의 문자를 건너띔
  • void close() : 스트림을 닫음
  • void write(int c) : int형으로 문자 데이터를 출력문자스트림으로 출력
  • void write(char[] buf, int offset, int length) : 문자열 buf의 offset위치부터 length 길이만큼을 출력스트림으로 출력
  • void newLine() : 줄바꿈 문자열 출력
  • void flush() : 남아있는 데이터를 모두 출력
profile
블로그 이전합니다! https://jyyoun1022.tistory.com/
post-custom-banner

0개의 댓글