Java/Theory

[Java/Theory]20. IO

양승길 2016. 5. 31. 13:03

20. IO

    JRE내부에는 자바를 실행하는 Bytecode가 있다. 

    이 Bytecode의 내, 외부를 조작 할 수 있는것이 IO Package다.

    IO에는 크게 5가지로 분류된다.


    ~Stream : 바이트(이진) 단위로 입출력을 수행하는 Class

    ~Reader / ~Writer :  Charactor 단위로 입출력을 수행하는 Class


//    File~ : 하드디스크의 파일을 사용하는 Class

//    Data~ : 자바의 원시 자료형을 출력하기 위한 Class

//    Buffered~ : 시스템의 버퍼를 사용하는 Class


 * InputStream / OutputStream (바이트 입출력)

      Abstract Class


 * Reader / Writer (문자 입출력)

      Abstract Class


      4개의 Abstract Class간에 is a 관계가 성립되지 않으나,

      Polymorphism을 위한 Consistency가 확립되어 있다.

      Checked Exception중에 IOException을 지원한다.


    *  InputStreamr과 Reader는 서로 다른 Datatype이지만

       InputStream으로 처리하던 중 Charactor를 읽어야 하는 상황이 온다면

       Reader로 변경이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
// 표준 입력장치를 추상화 한것이 System.in이다.
// API에 따르면 System.in의 Datatype은 InputStream으로 되어 있으나
// getClass()로 확인하면, BufferedInputStream으로 되어 있으므로
// 아래 구문은 Implicit Casting이 되어 read() Method를 사용 할 수 있다.
// read()는 Checked Exception중에 IOException을 지원하므로 try - catch에 포함시키도록 한다.
InputStream inputStream = System.in
Reader reader = new InputStreamReader(inputStream);
 
int i = reader.read();
char c = (char)i;
// 출력된 c중에 공백 2자가 있다. 이를 이용하여 알아서 잘 코딩 하셈.
System.out.println("입력한 값 : " + c);
cs


    * 출력을 할때, integer와 charactor를 변경하는 불편함이 있으므로, Writer를 이용하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
try{
    InputStream inputStream = System.in
    Reader reader = new InputStreamReader(inputStream);
 
    // 표준 입력장치를 추상화 한것이 System.out이다.
    // API에 따르면 System.out의 Datatype은 OutputStream으로 되어 있으나
    // getClass()로 확인하면, BufferedOutputStream으로 되어 있으므로
    // 아래 구문은 Implicit Casting이 되어 write() Method를 사용 할 수 있다.
    // write()는 Checked Exception중에 IOException을 지원하므로 try - catch에 포함시키도록 한다.
    OutputStream outputStream = System.out;
    Writer writer = new OutputStreamWriter(outputStream);
 
    while(true){
        int i = reader.read();
        writer.write(i);
        // JRE에는 사용자가 입력한 값들을 모아두는 Buffer가 있다.
        // flush()는 모아둔 Buffer들을 모두 내뱉어, 출력하는 함수다.
        // 때문에 flush를 어디에 작성해야 되는가를 잘 파악 해 두도록 한다.
        //writer.flush();  
 
        if((char)i =='x'){
            break;
        }
    } // end of while
 
    writer.flush();
    
    // Stream close
    // close에는 flush가 내포되어 있다.         
    reader.close();
    writer.close();
 
}catch(IOException e){
    e.printStackTrace();
}
cs


    * In = Read의 개념

      통상적으로 DataSource라고 부른다.


  * Out = Write의 개념

      통상적으로 DataTarget라고 부른다.      


  * Java IO의 특징

      - Simplex Modeling

        각 Class마다 Read와 Write기능이 따로 정의되어 있음.

      - FIFO

      - IO Block

        입력이 올 때까지 시스템은 Wating한다.

      - Flexible Structure

        Polymorphism이 입각한 Filter Stream이 구현되는 구조.

        ->Sink Stream : Data를 직접 주고 받는 단순 IO.

        ->Filter Stream : Sink Stream을 통해 들어오는 Data를 조작하는 Stream

           Ex 1 : 

1
2
BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader ( new FileInputStream ( "text.txt" , true) ) ) ;
// true => append 기존 파일에 있는 내용에 추가한다.
cs

        -> 조작 상황에 따라 Sink와 Filter를 활용한다.


  * Exception Handling의 주의할 점

      NullPointerException에 유의하도록 finally구문에 null check를 하는 습관을 기르도록 한다.


  * Relative Path

      Classpath에 지정된 곳을 Root로 출발하는 경로


  * Absolute Path

      File System을 Root로 두고 출발하는 경로


  * BufferedReader

      InputStream이나 Reader에 있는 read()는 한 binary씩 int형으로 반환되는 반면

      BufferedReader에 있는 readLine()은 해당 Data에서 한 줄씩 읽어들인다.(Scanning)