[그린컴퓨터] Server/JAVA(자바 JDK)

문자 단위 스트림 { Reader, Writer }

Ben의 프로그램 2023. 7. 5. 12:16
728x90

  • 바이트 단위 스트림은 문자, 영상, 음악 등 다양한 형태의 자료를 읽고 쓰는데 활용한다.
  • 반면 문자 단위 스트림은 String 문자 단위를 읽는데 사용한다. 특히나 한글 같이 1바이트 단위로 쓰지 못하는 것일수록 특히 그렇다. 
  • Reader 를 최상위 스트림으로 FileReader 스트림이 있으며, inputStreamReader 와 BufferedReader 는 보조 스트림이다. 

  • Reader 스트림은 문자를 2바이트로 끊어서 가져온다. 그것이 차이점이다. 
  • 예시를 한번 보자. 

  • reader Text 에 "안녕하세요" 라는 문장을 입력했습니다. 
package main;

import java.io.FileReader;
import java.io.IOException;

public class Ex8 {

	public static void main(String[] args) {
		try {
			FileReader fr = new FileReader("src/reader.txt");
			
			while (true) {
				int i = fr.read(); // 한 문자(2바이트)씩 읽기
				if (i == -1) {
					break;
				}
				System.out.println((char) i);
			}
		} catch (IOException e) {
			System.out.println(e);
		}
	}

}

  • 그 다음 fileReader 로 stream 을 생성한 다음 파일에서 2바이트 씩 읽어서 출력하게 코드를 작성했다. 

  • 출력 결과를 보면 한글도 잘 출력하는 것을 볼 수 있습니다. 

filewriter 예제

package main;

import java.io.FileWriter;
import java.io.IOException;

public class Ex9 {

	public static void main(String[] args) {
		try {
			FileWriter fw = new FileWriter("src/writer.txt"); // 문자 기반 출력 스트림 생성
			// 문자 하나 출력
			fw.write('A'); 
			// 문자열 출력
			fw.write("안녕하세요");
			// 특수기호 출력
			fw.write('\n');
			// 배열 출력
			char[] arr = {'a', 'b', 'c'};
			fw.write(arr);
			
			fw.flush(); // 버퍼에 있는 데이터 내보내기
		} catch (IOException e) {
			System.out.println(e);
		}
	}
}

  • Stream 은 버퍼라는 메모리를 활용하는데, write 하려고 하는 데이터를 버퍼에 모아놨다가 출력을 하게 된다. 즉, 버퍼의 메모리가 다 차지 않는 크기의 데이터를 우선적으로 출력하게 만들어주고 싶다면 flush( )  를 해주어야 한다. 

    위 코드에서 flush( ) 를 해주지 않으면 파일에는 변화가 생기지 않는 것을 알 수 있다. 

    특히 문자 stream 의 버퍼는 공간이 바이트보다 커서 flush 를 사용해주어야 한다. 

Filewriter 연습문제

Q. 1~10 숫자중 짝수만 텍스트파일에 출력하세요.
package quiz;

import java.io.FileWriter;
import java.io.IOException;

public class Quiz3 {

	public static void main(String[] args) {
		try {
			FileWriter fw = new FileWriter("src/quiz3.txt");
			
			for (int i = 1; i < 11; i++) {
				if (i % 2 == 0) {
					fw.write(i + " ");  // 2, 4, 6, 8, 10 을 출력해야하는데, fw 는 아스키코드로 인식한다.
					// 아스키 코드에서 숫자 0은 49번이다. 
					// 다른 방법으로는 위의 코드처럼 i + " " 로 char + char -> String 으로 
					// 출력할 수도 있다. 
					// 여기서 주의할 점은 (char)i 는 동작을 하지 않는데, 
					// (char)2 로 자바는 인식을 하는데 2에 해당하는 아스키 코드가 없기 때문에
					// 오류가 발생하게 된다. 
				}
			}
			fw.flush();
		} catch (IOException e) {
			System.out.println(e);		
		}
	}
}

  • int i = 2 일 때 (char)i 는 우리가 직관적으로 이해하는 것처럼 2가 되지 않는데, 아스키 코드에서 실제로 숫자 2는 아스키코드 50번이기 때문이다.