Develop

[java] 입출력 스트림 1부 (문자)

by hooni posted Apr 23, 2013
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
Java Input/Ouput Stream #1 (Character)

일반적으로 파일은 두가지 형태를 갖고 있습니다.
텍스트 형식의 파일과 바이너리 형식의 파일입니다.
정확하게 따지면 모든 데이터는 2진수로 저장 되기 때문에 모두 바이너리 파일이 되는것이 정상입니다.

굳이 이렇게 두가지 형식으로 나누는 것은 실제로 저장되는 파일의 데이터가 텍스트인 경우와 동영상, 사진, 오디오 등의 멀티미디어 파일일 경우에는 확실한 차이를 보이게 됩니다.

흔히 txt라는 확장자명을 갖는 파일은 메모장 파일이라고 합니다.
이 파일의 경우 저장된 데이터가 전부 문자입니다.
그러나 hwp, xls의 확장자명을 갖는 파일은 텍스트 정보가 들어 있지만 멀티미디어 정보도 같이 저장할 수 있습니다.
그렇다면 이는 텍스트 파일의 특징을 보유 할 수 없게 되는 것입니다.

이 차이를 쉽게 정리한다면 메모장으로 열어서 이상한 문자 코드로 출력이 된다면 이 파일은 바이너리 파일이라고 해야 한다는 것 입니다.
(이상한 코드가 나오게 되는 이유는 기계어 코드를 문자코드에 대응 시켰을 때 아무거나 대응 되는 것을 출력해주기 때문입니다.)

이런 문제 때문에 자바 입출력에서도 두가지 입출력 스트림을 사용합니다.

텍스트 파일을 다루게 되는 경우에는 문자스트림, 바이너리 파일을 다루게 되는 경우에는 바이트스트림을 사용해야 합니다.

바이너리 스트림의 경우에는 텍스트 파일을 다룰 수 있습니다.
텍스트 파일은 바이너리 파일이지만 세부적인 특징에서 다른 특징을 갖고 있기 때문에 흔히 두가지로 분류하는 것 입니다.

그럼 문자스트림 계층도를 보도록 합시다.

stream01.jpg

문자스트림 계층도는 java.io 패키지에 있는 Reader 클래스와 Writer 클래스를 이용합니다.
두 클래스는 추상 클래스이기 때문에 직접 사용할 수가 없습니다.
그래서 하위에 존재하는 클래스들이 이 두 추상 클래스가 제시하는 모든 기능을 구현했고 추가적으로 더 보완했습니다.
(API 문서를 참고하시면 더 자세한 구조를 파악할 수 있습니다.)

입력을 받아오는 예제 중 키보드 입력을 받아들이는 예제.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

예제 소스와 계층도를 보게 되면 모두 입력과 관련된 클래스를 이용했습니다.
Reader 추상클래스를 상속하여 만들어진 것이라 BufferedReader 클래스의 인수로 InputStreamReader 클래스를 사용할 수 있는 것 입니다.
Reader 이라는 조상으로 뻗어나간 자손이므로 둘의 관계는 공통점을 갖고 있어서 문제가 없는 것 입니다.
사촌지간이라고 비유 하면 되겠습니다.

그럼 키보드 입력을 받아들여 텍스트 파일로 저장하는 예제를 보도록 합시다.
import java.io.*;

class A{
    public static void main(String args[]){
        String str = null;
        try{
            BufferedReader br =
                new BufferedReader(new InputStreamReader(System.in));
            str = br.readLine();
   
            PrintWriter pw = new PrintWriter(new FileWriter("A.txt"));
            pw.println(str);
   
            br.close();
            pw.flush();
            pw.close();
   
        }catch(Exception e){}
  
        try{
            BufferedReader br = new BufferedReader(new FileReader("B.txt"));
   
            while((str = br.readLine()) != null){
                System.out.println(str);
            }
            br.close();   
        }catch(Exception e){}
    }
}

클래스와 메소드는 API와 문자스트림 계층도를 확인하시면 충분히 파악이 가능하기 때문에 별도 설명은 안하겠습니다.

여기서 약간 이해 할 수 없는 부분이 있다면 flush 메소드를 사용해야 하는 부분과 close 메소드를 실행해야 하는 부분입니다.
파일을 입출력하게 되면 그 끝이 어딘가를 알려줘야 합니다.
만약 close를 하지 않으면 문제가 되는 경우가 생기게 됩니다.
그리고 파일 저장의 경우는 저장해야 할 데이터 값이 너무 작으면 저장을 안하는 경우가 존재합니다.
그 작은 데이터 값까지 저장해야 하기 때문에 반드시 해줘야 합니다. 

텍스트 파일을 일게 되면 공백문자도 문자라고 할 수 있는 것은 당연합니다.
그러나 문단이 나눠지게 되는경우 쉽게 말해 빈 라인이 생기는 경우 아무런 문자가 없다고 생각하기 쉽습니다.
그러나 우리 눈에 보이지 않는 것이 있습니다.
컴퓨터는 텍스트를 저장하게 되면 공백문자, 탭, 줄바꿈 등도 전부 시스템이 정해놓은 특수문자로 저장합니다.

단지 사람 눈에만 달라 보이게 되는 것이지요.(보기 편해야 하니까요.)
그렇기 때문에 공백라인도 문자가 존재하는 것입니다.
아마 윈도우 시스템 환경에서는 줄바꿈이 " ", 리눅스나 유닉스에서는 " " 일 것입니다.

그래서 종종 메모장으로 텍스트파일을 얼게 되면 줄바꿈 대신 이상한 특수문자가 택스트 사이 사이에 껴 있는 것을 볼 수 있습니다.
(OS시스템 환경에 따른 줄바꿈문자가 달라서 생기는 문제입니다.)

추가적으로 덧붙이자면 예제 연습은 필수입니다. 

감사합니다.