본문 바로가기
Java

BufferedReader, BufferedWriter, StringTokenizer

by 이쟝 2022. 1. 17.

버퍼(buffer)

- 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 임시 메모리 영역

- 입출력 속도 향상을 위해 버퍼 사용

- 버퍼 플러시(buffer flush): 버퍼에 남아있는 데이터를 출력시킴(버퍼를 비우는 동작)

- 버퍼를 이용한 입력 BufferedReader 버퍼를 이용한 출력 BufferedWriter

 

- BufferedReader/BufferedWriter는 Buffer에 있는 IO 클래스

- 입력된 데이터가 바로 전달되지 않고 중간에 버퍼링이 된 후에 전달된다.

- 버퍼스트림을 InputStreamReader / OutputStreamWriter를 같이 사용해 버퍼링을 하게 되면 입출력 스트림으로부터 미리 버퍼에 데이터를 갖다 놓기 때문에 보다 효율적인 입출력이 가능하다.

더보기

스트림(stream)

- I/O에서 데이터를 운반하는데 사용되는 연결통로로 입력스트림(input stream)과 출력스티림(output stream)이 필요하다. (14장의 람다와 스트림과는 다른 개념)

1.BufferedReader

- Enter만 경계로 인식하고 받은 데이터가 String으로 고정(입력받은 데이터를 가공하는 작업이 불필요)

- 주로 쓰는 메서드는 readLine( )close( )

- readLIne( )은 입력값으로 들어온 데이터를 한 줄로 읽어서 String으로 바꾸는 메서드로 무조건 한 줄만 읽는다!!

 

사용법

 

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

String s = bf.readLine();                 // String

int i = Integer.parseInt(bf.readLine());  // Int (String -> int 형변환)

 

*주의할 점*

- readLine( )리턴시 리턴값이 String으로 고정되서 String이 아닌 다른 타입으로 입력 받으려면 형변환 필수

- 예외처리를 꼭 해주어야 한다 (1) throws IOException import java.io.IOException; (3) try-catch

 

한 줄에 입력을 여러 개 받아야 하는 상황??

-> StringTokenizer 클래스 또는 String클래스의 메서드인 Split를 이용해서 공백을 기준으로 나누면 된다.

 


 

StringTokenizer?

- 사용자가 지정한 구분자로 문자열을 나누어 주는 클래스.

- 앞서 말했듯이 readLine() 은 한 행을 전부 읽기 때문에 공백단위로 입력해 준 문자열을 공백단위로 분리해주어야 문제를 풀 수 있다.

구분자로 문자열을 나눠주면 더 이상 나눌 수 없는 요소들을 Token이라고 한다.

) 전화번호 010-1234-5678 이라는 번호에서 -는 구분자이고 숫자는 Token이다.

 

String s = "2022 2 15";
StringTokenizer tokenizer = new StringTokenizer(s); //공백을 기준으로 문자열 s 나누기 위한 객체

-> 구분자를 적어주지 않으면 공백을 기준으로 나눈다.

 

String s = "2020-02-15";
StringTokenizer tokenizer = new StringTokenizer(s, ", ");

-> 쉼표를 구분자로 나누고 싶으면 생성자의 인자로 “, “ 이렇게 넣어주면 된다.

 

StringTokenizer의 메서드 

 

int countTokens() 남아있는 토큰의 개수를 반환한다.
boolean hasMoreTokens() 남아있는 토큰이 있으면 true, 이상 토큰이 없으면 false
String nextToken() 토큰을 꺼내온다.

 

- StringTokenizer 객체는 소모적이라서 사용하면 다시 사용할 없어서 다시 사용하고 싶다면 객체를 새로 만들어야 한다. 

- 이미 소모한 객체에서 토큰을 꺼내려고 하면 다음과 같이 NoSuchElementException 예외가 발생한다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException  {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); // 선언
		String s = bf.readLine();                 // 입력을 5,4로 받음
		
		StringTokenizer st = new StringTokenizer(s); // StringTokenizer 인자값에 입력 문자열 넣음
		// StringTokenizer st = new StringTokenizer(br.readLine());
		int a = Integer.parseInt(st.nextToken()); // 5
		int b = Integer.parseInt(st.nextToken()); // 4
		
		String[] arr = s.split(" "); 
		System.out.println(a);  // 5
		System.out.println(b);  // 4
		
		for (String k:arr)
			System.out.println(k); // 5와 4 출력
	}
}

 

더보기

-> readLine()메소드를 이용해서 입력을 받으면 한 줄을 입력으로 받기 때문에 5 4 와 같이 공백을 넣어서 입력을 해도 공백을 포함해서 버퍼에 넣는다. 공백을 기준으로 나누기 위해서는 첫번째로 StringTokenizer 클래스를 이용할 수 있고 번째로 Split(" ")메소드를 이용해서 입력 받은 문자를 나눌 수 있다.

 


2.BufferedWriter

- System.out.print("");와 같이 동일한 기능인 출력을 하는 메소드

- BufferedWriter 함수 또한 버퍼를 이용하기 때문에 성능이 print메소드 보다 좋아서 많은 양의 출력이 필요하다면 BufferWriter를 사용하는 것이 좋다.

 

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); 
String str = "abcdef";    // 출력할 문자열
bw.write(str + "\n");     // 출력(String형만 출력가능, 만약 다른형이면 형변환 필요)
bw.newLine();             // 줄바꿈
bw.flush();               // Write로 담은 내용 출력 후, 버퍼를 비움
bw.close();               // 스트림을 닫음

 

- bw.write에는 System.out.println();과 같이 자동개행기능이 없어서 개행을 해주어야 할 경우에는 \n를 통해 따로 처리해주어야 한다.

- BufferedWriter 의 경우 bw.write를 통해 buffer에 저장하고 그 후  반드시 flush() / close() 를 반드시 호출해 주어 flush( )로는 버퍼에 있는 내용들을 출력하고, close()로는 스트림을 닫아 주어야 한다. 

-> BufferedReader br = new BufferedReader(New InputStreamReader(System.in));   입력

    BufferedWriter bw = new BufferedWriter(New OutputStreamWriter(System.out));  출력

 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main15552 {

	public static void main(String[] args) throws IOException  {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  // 선언
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
		// br.nextLine()로 String형을 받아서 Int형으로 변환 
		int N = Integer.parseInt(br.readLine()); 
 
		for(int i = 0; i < N; i++) {  // 받은 Int형의 크기 만큼 for문 실행
			/* 주어지는 두 정수를 문자열 분리를 위해 매 반복마다 StringTokenizer을 생성과 동시에
			   문자를 입력받는다, " "는 구분헤서 배열로 받기 위해서*/
			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			
			int a = Integer.parseInt(st.nextToken()); // 띄어쓰기로 구분된 첫 번째 하나를 string -> int
			int b = Integer.parseInt(st.nextToken()); // 띄어쓰기로 구분된 두 번째 하나를 String -> int
			bw.write(a+b + "\n");                     // reader로 읽기 위해서 write안에 int형으로 바꿔준 값을 넣고 개행
		
		}
		
//		for(int i = 0; i < N; i++) {  // 위의 for문과 동일한 식
//			StringTokenizer st = new StringTokenizer(br.readLine()," "); 
//			bw.write((Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken()))+ "\n");
//		}

		br.close();  
      
		bw.flush();  
		bw.close();
	}
}

 

https://st-lab.tistory.com/41

 

JAVA [자바] - 입력 뜯어보기 [Scanner, InputStream, BufferedReader]

이 글을 지금 이 시점에 써야 할까 고민을 많이 했다. 사실 자바를 그냥 다룰 줄만 아는 것에 목표를 둔다면 이 글이 무의미할 수도 있다. 그러나 자바에 대해 조금이라도 관심이 있고 더 배우고

st-lab.tistory.com

 

'Java' 카테고리의 다른 글

재귀호출( recursive call)  (0) 2022.01.13
ChoiceFormat과 MessageFormat  (0) 2022.01.08
Java.time 패키지  (0) 2022.01.01
Math클래스의 round와 random 메소드  (0) 2021.12.29