본문 바로가기
JAVA

[JAVA] 입출력 스트림 (I/O Stream)

by 주옹스 2020. 8. 18.

- 입출력(Input/Output) 스트림(Stream) 이란?

 

   * 자바의 모든 데이터 입출력은 스트림이라는 개념에 의해 이루어진다.

 

   * 스트림은 응용프로그램과 입출력 장치를 연결하는 소프트웨어 모듈로서, 입출력 장치와 응용프로그램

     사이에서 데이터가 순서대로 전송된다.

 

   * 데이터 입출력 시 모든 데이터를 형태와는 관계없이 일련된 흐름으로 전송하는 것이 스트림 입출력 모델의

     기본 개념.

 

   * 입출력 스트림 관련 클래스 및 인터페이스는 java.io 패키지에 있다.

 

 

 

[ 종류 ] 

  1. 바이트 스트림(byte stream) : 1byte단위로 입출력 수행. 기본 입출력 단위

  2. 문자 스트림(character stream) : 2byte의 문자 단위로 입출력 수행

 

 

[ 특징 ]

  1. 스트림에는 입력 스트림(Input Stream), 출력 스트림(Output Stream)이 있다.

  2. 스트림은 FIFO 구조이다. -> 먼저 들어간 문자가 출력안되면 뒤에 문자 출력안됨.

  3. 스트림은 단방향이다.

  4. 스트림은 지연(blocking)될 수 있다.

 

 

[ 주요 입출력 예외 클래스 ]

   1.  java.io.IOException

      : 입출력 처리 중 예외가 발생할 때 IOException이 발생하며, 대부분 입출력 관련 예외 클래스의

       상위 클래스 이다.

 

   2.  java.io.FileNotFoundException

      : 지정된 경로에 파일이 존재하지 않는 경우 발생하는 예외

 

   3.  java.io.EOFException

      :  입력 도중 예기치 않게 파일이 끝나 스트림 종료에 도달했음을 알리는 예외로, 주로 데이터 입력 스트림의 종료를 알리기 위해 사용.

 

 

 

 

 

- System.in

  : 표준 입력 스트림으로, 열려 있어 바로 사용 가능하다.

    -> 원형 : public static final InputStream in

    -> 클래스 : java.lang.System

 

 

- System.out

  : 표준 출력 스트림으로, 열려 있어 바로 사용 가능하다.

    -> 원형 : public static final PrintStream out

    -> 클래스 : java.lang.System

 

 

- System.out

   : 표준 에러 출력 스트림으로, 열려 있어 바로 사용 가능하다.

 

 

 

 

 

 

- 바이트 스트림 (Byte Stream) ?

   

  * 스트림의 기본 입출력 단위는 바이트(byte)이다.

  

  * 1바이트(8bit) 단위로 입출력을 수행

 

  * 2진 데이터의 입출력이 가능

 

  * 모든 바이트 스트림 클래스는 InputStream, OutputStream클래스의 서브 클래스.

 

주요 바이트 스트림 클래스의 계층도

 

 

 

 

 

 

- 문자 스트림 (Character Stream) ?  

   (거의, 메모장 만들때만 사용! ==> 사진이나 이모티콘 여러가지가 바이트형이기 때문)

 

 

  * 2바이트(16bit)의 유니코드 문자를 입출력 하기 위한 스트림.

 

  * 문자 단위로 입출력을 수행

 

  * 모든 문자 스트림 클래스는 Reader 및 Write 클래스의 서브 클래스.

 

주요 문자 스트림 클래스의 계층도

 

 

 

 

 

 

 

- Bridge Stream ? 

 

  * 1byte stream을 2byte stream으로 변환해주는 stream. (바이트 스트림을 문자스트림으로 변환)

 

  * Bridge Stream에는 InputStreamReader와 OutputStreamWrite클래스가 있다.

 

 

 

 

 

 

[여러 스트림 클래스]

 

1.  java.io.InputStream 클래스

    : InputStream 클래스는 추상 클래스로, 모든 바이트 입력 스트림 클래스의 최상위 클래스.

 InputStream 주요 메소드

 

 

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
36
37
38
package ex0818;
 
import java.io.IOException;
 
public class InputStream_read_write {    
    public static void main(String[] args) {
        int data;
        char ch;
        
        // System.in : InputStream 객체. byte 스트림
        // InputStream 의 read() : 1byte를 읽어 ascii 코드 반환. ==> 2byte를 읽으려면 2번읽어야함.
        
        try {
            //ABC 엔터 => 3+2번읽어들임. 65-> 영어는 1바이트, 66 67 (13 10) -> 엔터는2바이트
            //대한민국 엔터 => 8+2번읽어들임. 180 235 199 209 185 206 177 185 (13 10)
            
            System.out.print("문자열 [ctrl+Z:종료] ?");
            
            while((data=System.in.read())!=-1) {
                
                //System.out.println(data);
                
                ch = (char)data;// ==> 2byte)
                
                System.out.print(ch); //대한민국 ->´???¹?±¹ ==> 한번깨지면 회복불가능
                                      //한글은 깨짐. 2byte문자를 1byte만 읽어서 2byte로 출력하므로
                
                //System.out.write(ch); //대한민국 
                //한글 깨지지 않음. 2byte중 하위 1byte만 출력.
                
                //System.out.write(data);// -->(ex. write는 4byte를 넣어도 1byte만 읽음.)
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

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
package ex0818;
 
import java.io.IOException;
 
public class InputStream_read_ex1 {    
    public static void main(String[] args) {
        
        int n,data;
        
        //123 엔터 =? 49 50 51 (13 10)->엔터
        n=0;
        try {
            System.out.print("수?");
            while((data=System.in.read())!=13) { //엔터치면 나가라는 말! 
                data = data-48;
                n = n*10+data;
            }
            
            int s = 0;
            for(int i = 1; i<=n; i++)
            {
                s+=i;
            }
            System.out.println("결과 : "+ s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

 

 

2.  java.io.OutputStream 클래스

    : OutputStream 클래스는 추상 클래스로, 모든 바이트 출력 스트림 클래스의 최상위 클래스.

OutputStream 주요 메소드

 

 

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
package ex0818;
 
public class OutputStream_write_ex1 {    
    public static void main(String[] args) {
        
        // System.out : PrintStream
        // PrintStream : 다양한 출력이 가능한 출력 스트림(필터)
        // IOException이 발생하지 않는다.
        System.out.write(65); //하위 1byte를 출력 버퍼로
        System.out.write(66);
        System.out.write(67);
    
        System.out.write(180);
        System.out.write(235); // 180+235 : 대
        
        System.out.write(199);
        System.out.write(209); // 199+209 : 한
        
        System.out.flush(); 
        // 출력버퍼가 차지 않으면 출력장치로 보내지 않으므로 
        // flush()를 통해 출력 장치로 보냄
        // System.out.write(10); 만 출력해도 출력됨.
    }
}
 
cs

 

 

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
package ex0818;
 
public class OutputStream_write_ex2 {    
    public static void main(String[] args) {
        
        int data;
        
        try {
            //입출력 스트림은 앞에 글자가 나가지 않으면 뒤에 글자가 나갈 수 없음. FIFO
            //컴퓨터 기억장치 중 가장 빠른거 -> 레지스터
            System.out.print("ABCDEF 입력후 엔터: ");
            
            data = System.in.read(); // 65 
            System.out.write(data); // A
            
            System.in.skip(2); // B,C랑 읽어서 버리고 싶을때. 
                               // skip : 읽어서 버리는거
             
            data = System.in.read(); // 68
            System.out.write(data); // D
            
            System.in.skip(4); // 엔터까지 합쳐서 4byte버림! ==> E F 13 10 
            System.out.flush(); // 버퍼가 차지 않으면 임시기억장치에 있는 글자 출력안함!
                                // 버퍼의 내용을 출력 장치로...
            
            
        } catch (Exception e) {
            // e.printStackTrace();
        }
    }
}
 
cs

 

 

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
package ex0818;
 
import java.io.IOException;
import java.io.OutputStream;
 
public class OutputStream_ex1 {
    public static void main(String[] args) {
         byte[] b = {65,66,67,68,69,70};
         
         try {
            //OutputStream : 출력 byte 스트림
            //PrintStream 과 다름!
            OutputStream os = System.out;
            
            os.write(b);  // ABCDEF
            System.out.println();
            
            os.write(b,2,3); //CDE (index:2 ~ 3개)
            System.out.println();
            
            os.write(b,0,b.length); //ABCDEF
            //write가 flush를 안해도 buffer로 보내는 것이 있고 아닌것이 있어서 그냥 flush하는 것이 나음!
            
            os.close();
            
            System.out.println("end...."); //출력 안됨! ==> 출력 stream close 해버려서!
        } catch (IOException e) {
          e.printStackTrace();
        }
    }
}
 
cs

 

 

 

3.  java.io.Reader 클래스

    : Reader 클래스는 문자 입력을 위한 추상 클래스로, 모든 문자 입력 스트림의 최상위 클래스.

Reader클래스 주요 메소드

 

4. java.io.InputStreamReader 클래스

   : InputStreamReader 클래스는 바이트 stream으로부터 문자 stream과 중개의 역할을 해서 바이트

     데이터를 읽어 들여 그것을 지정하는 "문자 인코딩" 에 따라 변환함.

InputStreamReader클래스 주요 메소드

 

 

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
package ex0818;
 
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
 
public class Reader_ex1 {
    public static void main(String[] args) {
        int data;
        //char ch;
        
        try {
            //InputStreamReader : byte stream을 문자 스트림으로 변환(bridge stream)
             Reader rd = new InputStreamReader(System.in); //System.in은 바이트 스트림
             
             System.out.print("입력 [ctrl+z:종료] ?");
             while((data = rd.read())!=-1){
                
                 // 한글, 영문자 모두 한번에 한문자씩 입력
                System.out.println(data); // 대한민국 -> 32 45824 54620 48124 44397 13 10 --> 2byte출력이라
                                            // ABC  -> 65 66 67 13 10
                 
                //ch = (char)data;
                //System.out.write(ch); // 한글 깨짐. 2byte문자를 1byte만 출력하므로
                
                
             }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

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
package ex0818;
 
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
 
public class Reader_ex2 {
    public static void main(String[] args) {
        int data;
        
        try {
            
             Reader rd = new InputStreamReader(System.in); 
             Writer wt = new OutputStreamWriter(System.out); 
             
             System.out.print("문자열 [ctrl+z:종료] ?");
             while((data = rd.read())!=-1){
                wt.write(data); // 문자 (하위 2byte) 출력
             }
             wt.flush();
             
             // 출력하게 나오게하려면 엔터치고 ctrl+z 반드시 눌러야함!! (버퍼가 차지 않았기 때문에)
             
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

5. java.io.Write 클래스

   : Write 클래스는 문자 출력을 위한 추상클래스로, 모든 문자 출력 스트림의 최상위 클래스.

Write클래스 주요 메소드

 

 

6. java.io.OutputStreamWrite 클래스

   : 문자 출력 스트림으로 부터 바이트 출력 스트림의 중개의 역할을 담당. 바이트 스트림에 기입해진

    문자는, 지정된 charset를 사용해 바이트에 encode된다.

 

OutputStreamWirte클래스 주요 메소드

'JAVA' 카테고리의 다른 글

[ JAVA ] Thread  (0) 2020.08.20
[JAVA] 파일처리 예시  (0) 2020.08.18
[JAVA] 생성자  (4) 2020.08.11
[JAVA]인터페이스 (Interface)  (1) 2020.08.11
[JAVA] String _ API  (0) 2020.08.06