ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Camel][Java] 문자 스트림(Stream) / FileReader, FileWriter, BufferedReader, BufferedWriter
    Java/개념 정리 2020. 3. 4. 21:40

    문자 스트림 

     이전 포스팅에서 다뤘던 입출력 스트림은 Byte 단위로 입출력이 이루어지는 Byte 스트림이었습니다. 하지만 Byte 단위로만 입출력이 가능한 것이 아닙니다. 문자 단위로 입출력이 이루어지는 문자 스트림이 존재하기 때문입니다. 

     

     Java는 유니코드 기반으로 문자를 인코딩합니다. 하지만 우리가 흔히 일상에서 사용하는 Windows나 Linux의 경우에는 Java와 다른 표준으로 문자를 인코딩합니다. 그렇다면 Windows 운영체제에서 실행되는 Java 프로그램에서 파일에 문자 데이터를 저장하고, 이것을 Windows 응용프로그램으로 읽어내려면 어떤 기준으로 인코딩해 저장해야할까? 정답은 'Windows 기준으로 인코딩해야한다'입니다. 더 나아가, Windows가 아닌 다른 운영체제에서는 또 다른 인코딩 방식을 사용하기 때문에 개발자 입장에서는 골치아픈일이 아닐 수 없습니다.

     

     그렇다면 이런 문제를 해결하기 위해 파일을 대상으로 문자를 입출력할 때, 각 운영체제의 기본 인코딩방식에 맞춰서 자동으로 문자가 인코딩되어 저장되는 스트림은 없을까? 이것을 가능하게하는 것이 문자 스트림입니다. 

     

     입출력 스트림에 대한 이전 포스팅을 참고하시면 도움이 될 수 있습니다. 

    2020/03/03 - [Java] - [Camel][Java] InputStream & OutputStream (파일 입출력)

     

     

     

    FileReader & FileWriter 

     Byte 스트림의 최상위 클래스는 InputStream과 OutputStream이었습니다. 그렇다면 문자 스트림의 최상위 클래스는 무엇일까? 문자 스트림의 최상위 클래스는 Reader와 Writer입니다. 문자를 단위로 하는 파일입출력 스트림은 FileReader, FIileWriter 입니다. 

     

     Reader의 대표적인 메소드는 아래와 같습니다.

    public int read() throws IOException
    public abstract int read(char[] cbuf, int off, int len) throws IOException

     첫 번째 메소드는 파일로부터 읽은 문자 하나를 반환하고, 두번째 메소드는 최대 len 개의 문자를 읽고 cbuf라는 배열에 인덱스 off의 위치에서부터 문자를 저장합니다. 두 메소드 모두 더 이상 읽을 문자가 없다면 -1을 반환하고, 두 번째 메소드는 읽은 문자의 수를 반환합니다. 

     

     Writer의 대표적인 메소드는 아래와 같습니다.

    public void wirte(int a) throws IOException
    public abstract void write(char[] cbuf, int off, int len) throws IOException

     첫 번째 메소드는 파일에 문자 하나를 저장하고, Java에서 문자는 2Byte로 표현되므로 나머지 2Byte는 무시합니다. 두번째 메소드는 cbuf라는 배열에 인덱스 off의 위치에서부터  len 개문자를 저장한 뒤 파일에 저장합니다. 

     

     이와 같은 문자 스트림을 사용해 2개의 문자를 전송해 파일에 저장했다면 총 4Byte의 데이터를 전송한 것입니다. 하지만 파일의 크기를 확인해 보면 4Byte가 아닌 2Byte인 것을 확인 할 수 있습니다. 문자 스트림을 사용함으로써 해당 운영제체의 기본 인코딩 방식에 맞춰서 인코딩되었기 때문입니다. 

     

     이러한 문자 스트림의 특징으로 인해, 우리는 파일에 저장된 문자를 Java 프로그램에서 인식할 수 있도록 할 수 있습니다. 

     

    FileReader & FileWriter 예제 코드

    FileWriter 예제 코드

    class FileWriterExample {
    	public static void main(String[] args) {
        	char c1 = 'C';
            char c2 = 'A';
            char c3 = 'M';
            char c4 = 'E';
            char c5 = 'L';
            
            
            Writer out = new FileWriter("camel.txt");
            out.write(c1);
            out.write(c2);
            out.write(c3);
    	out.write(c4);
            out.write(c5);
            
            out.close();
        }
    }

    FileWriter 예제 코드를 통해 생성된 파일을 읽는 FileReader 예제 코드

    class FileReaderExample {
    	public static void main(String[] args) {
        	char[] cbuf = new char[10];
            int cnt;
            
            Reader in = new FileReader("camel.txt");
            cnt = in.read(cbuf, 0, cbuf.length);
            
            for(int i =0; i< cnt; i++) {
            	System.out.println(cbuf[i]);
            }
            
            in.close();
        }
    }

     

     

     

     

     

    BufferedReader & BufferedWriter

     문자 스트림에도 Byte 스트림처럼 버퍼 필터 스트림을 추가할 수 있습니다. 문자 스트림의 입출력 버퍼 필터 스트림은 BufferedReader와 BufferedWriter입니다. 이 스트림들은 기본적인 사용방법과 제공기능이 Byte 스트림의 버퍼 필터 스트림과 별반 차이가 없습니다. 문자열의 입출력기능을 담당하는 클래스의 메소드는 다음과 같습니다. 

    public String readLine() throws IOException   // BufferedReader 클래스의 메소드
    public void write(String str) throws IOException // Writer 클래스의 메소드

     여기서 이상다하고 생각될 수 있는 점은 문자열의 출력은 출력 스트림의 최상위 클래스인 Writer 클래스에서 제공하지만, 입력의 경우는 최상위 클래스가아니며 필터 스트림 중 하나인 BufferedReader 클래스에서 제공한다는 점입니다. 즉, 문자열의 입력을 원한다면 반드시 BufferedReader 클래스를 필터 스트림으로 연결해야 한다는 것입니다. 

     

     그렇다면 왜 문자열 입력의 경우 BufferedReader를 필터 스트림으로 이용해야하는 것일까? 그 이유는 문자열의 입력은 버터링의 유무에 따라 성능 차이가 크게 달라질 수 있기 때문입니다. BufferedReader를 필터 스트림으로 사용함으로써 반드시 버퍼링을 하라는 의미입니다.

     

     하지만 이러한 특징은 문자열의 입력뿐만아니라 출력의 경우에도 예외는 아닙니다. 그렇기 때문에 문자열의 입출력에서는 버퍼 필트 스트림을 연결하는 것이 좋습니다. 

     

    BufferedReader & BufferedWriter 예제 코드

    BufferedWriter 예제코드

    class BufferedWriterExample {
    	public static void main(String[] args) {
        	
            	BufferedWriter out = new BufferedWriter(new FileWriter("camel.txt"));
            
            	out.write("Camel's Info");
            	out.nextLine();
            	out.write("Camel is tall.");
            	out.nextLine();
            	out.write("Maybe, 183cm");
            	out.nextLine();
            
            	out.close();
        	}	
    }

    BufferedReader 예제코드

    class BufferedReaderExample {
    	public static void main(String[] args) {
        	
            	BufferedReader in = new BufferedReader(new FileReader("camel.txt"));
            
            	String str;
            
            	while (1) {
            		str=in.readLine();
                		if (str == null) break;
                		System.out.println(str);
            	}
            
            	in.close();
        }
    }

    댓글

Camel`s Tistory.