ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | I/O 보조 스트림
    JAVA/JAVA 2020. 2. 6. 23:04

    보조 스트림

    입출력 대상이 되는 파일이나 네트워크를 직접 읽거나 쓰는 기능은 없음
    말 그대로 보조 기능을 추가하는 스트림

    다른 스트림을 감싸고 있다는 뜻에서 Wrapper 스트림이라고도 함

    • 보조 스트림처럼 다양한 기능을 제공하는 클래스를 디자인 패턴에서 '데코레이터(decorator)'라고 함
    • 보조 스트림의 생성자에 항상 기반 스트림만 매개변수로 전달되는 것은 아님
      내부적으로 기반 스트림을 포함한 보조 스트림 역시 전달 가능
      → 하나의 기반 스트림에 여러 보조 스트림 기능이 추가됨

    FilterInputStream & FilterOutputStream

    보조 스트림 상위 클래스
    보조 스트림은 자료 입출력을 직접 할 수 없기 때문에 다른 기반 스트림을 포함해야 함


    생성자

    생성자 설명
    protected FilterInputStream(InputStream in) 생성자의 매개변수로 InputStream을 받음
    public FilterOutputStream(OutputStream out) 생정자의 매개변수로 OutputStream을 받음
    • 두 클래스 모두 다른 생성자는 제공하지 않음
    • 다른 스트림을 매개변수로 받아서 상위 클래스를 호출해야 함
    • 두 스트림을 직접 사용하는 경우는 거의 없고, 이를 상속한 하위 클래스 사용

    InputStreamReader & OutputStreamWriter

    바이트 스트림을 문자로 변환해 주는 보조 스트림

    • System.in과 System.out 모두 바이트 스트림이기 때문에 콘솔 화면에서 한글을 읽으려면
      InputStreamReader를 사용해야 함
    • 채팅 프로그램 작성시 바이트 단위로 입출력을 사용하면 영어로만 대화 해야함
      이럴 때 InputStreamReader나 OutputStreamWriter를 활용해 문자로 변환하여 사용하면 됨

    InputStreamReader 생성자

    생성자의 매개변수로 바이트 스트림과 문자 세트 지정 가능

    생성자 설명
    InputStreamReader(InputStream in) InputStream 클래스를 매개변수로 받아 Reader 생성
    InputStreamReader(InputStream in, Charset cs) InputStream과 Charset 클래스를 매개변수로 받아 Reader 생성
    InputStreamReader(InputStream in, CharsetDecoder dec) InputStream과 CharserDecoder를 매개변수로 받아 Reader 생성
    InputStreamReader(InputStream in, String charsetName) InputStream과 String으로 문자 세트 이름을 받아 Reader 생성

    ※ OutputStreamWriter의 생성자도 위와 동일한 구성이며 세 번째 생성자의
    CharsetDecoder(해석) 매개변수 대신 CharsetEncoder(포장) 를 받는다는 점만 다름


    Buffered 스트림

    입출력이 한 바이트나 한 문자 단위로 이루어지면 그만큼 프로그램 수행 속도가 느려지는데,
    Buffered 스트림은 단위들을 배열로 묶어서 더 빠르게 입출력을 실행할 수 있는 버퍼링 기능을 제공함

    • Bufferd 스트림은 내부적으로 8,192 바이트 크기의 배열을 가짐
    • 이미 생성된 스트림에 배열 기능을 추가해 더 빠르게 입출력을 실행할 수 있는 버퍼링 기능을 제공함

    Buffered 스트림 클래스

    스트림 클래스 설명
    BufferedInputStream 바이트 단위로 읽는 스트림에 버퍼링 기능 제공
    BufferedOutputStream 바이트 단위로 출력하는 스트림에 버퍼링 기능 제공
    BufferedReader 문자 단위로 읽는 스트림에 버퍼링 기능 제공
    BufferedWriter 문자 단위로 출력하는 스트림에 버퍼링 기능 제공

    BufferedInputStream 생성자

    생성자 설명
    BufferedInputStream(InputStream in) InputStream 클래스를 생성자의 매개변수로 받아 BufferedInputStream 생성
    BufferedInputStream(InputStream in, int size) InputStream 클래스와 버퍼 크기를 생성자의 매개변수로 받아 BufferedInputStream 생성

    ※ BufferedOutputStream은 OutputStream,
    BufferedReader는 Reader,
    BufferedWriter는 Writer 클래스를 생성자의 매개변수로 받음
    스트림이 입력 스트림인지 출력 스트림인지, 바이트 단위인지 문자 단위인지에 따라 사용하면 됨


    BufferedReader 메소드

    메소드 설명
    int read() BufferedReader 클래스 일반 메소드
    문자 하나를 읽어 들임문자를 0~65535의 정수로 읽어 들이며 읽을 문자가 없는 경우 -1 리턴
    int read(char[] cbuf, int off, int len) BufferedReader 클래스 일반 메소드
    문자 배열 cbuf 의 off 인덱스부터 len 개수만큼의 문자를 정수로 읽어 들임
    문자가 없는 경우 -1 리턴
    String readLine() BufferdReader 클래스 일반 메소드
    입력된 텍스트를 줄 단위('\n')로 읽어 들임
    읽어 들일 문자가 없어지면 'null' 반환
    void close() BufferedReader 클래스 일반 메소드
    스트림 사용 후 메모리에서 스트림을 해제할 때 사용

    ※ 스트림 클래스 메소드는 입/출력 메소드로 기능이 크게 구분되며
    입력 메소드와 출력 메소드 각각은 클래스마다 이름과 기능이 유사하기 때문에

    이클립스로 작업시 Shift + F2를 눌러서 공식 API 문서를 참조하는 것이 도움이 됨


    예제_BufferedReader & InputStreamReader 

    package j200206;
    
    import java.io.*;
    
    public class FilterTest {
    
        // 입출력시에는 반드시 예외 처리를 해야함!
        public static void main(String[] args) throws Exception {
    
            /* 
            표준 입력 장치로 입력을 받는데(System.in), 
            한글이 깨지지 않도록 하고(InputStreamReader),
            한 번에 많은 양의 데이터를 읽어 들이도록 함(BufferedReader)
            */
            BufferedReader bb = new BufferedReader(new InputStreamReader(System.in));
    
            // 변수 선언
            String name;
            int kor, eng, total;
    
            // 변수마다 값을 입력 받음
            System.out.println("이름은?");
            name = bb.readLine();
    
            System.out.println("국어 점수는?");
            // String으로 입력되기 때문에 int형으로 변환해서 저장
            kor = Integer.parseInt(bb.readLine());
    
            System.out.println("영어 점수는?");
            eng = Integer.parseInt(bb.readLine());
    
            // 스트림 사용 후 메모리 해제
            bb.close();
    
            // 총점 계산 및 출력
            total = kor + eng;
            System.out.println(name + "의 시험 점수는 총 " + total + "점입니다.");
            
            /*
            이름은?
            홍길동
            국어 점수는?
            40
            영어 점수는?
            50
            홍길동의 시험 점수는 총 90점입니다.
            */
        }
    
    }

    DataInputStream & DataOutputStream

    자바의 기본 자료형에 맞게 자료를 입출력하는 보조 스트림

    메모리에 저장된 0,1 상태를 그대로 읽거나 쓰기 때문에 자료형의 크기가 보존됨


    생성자

    생성자 설명
    DataInputStream(InputStream in) InputStream을 생성자의 매개변수로 받아 DataInputStream 생성
    DataOutputStream(OutputStream out) OutputStream을 생성자의 매개변수로 받아 DataOutputStream 생성

    DataInputStream 메소드

    자료형별 메소드가 있으며, 자료를 쓸 때 사용한 메소드와 같은 자료형의 메소드로 읽어야 함

    메소드 설명
    byte readByte() 1바이트를 읽어 반환
    boolean readBoolean() 읽은 자료가 0이 아니면 true, 0이면 false 반환
    char readChar() 한 문자를 읽어 반환
    short readShort() 2바이트를 읽어 정수 값 반환
    int readInt() 4바이트를 읽어 정수 값 반환
    long readLong() 8바이트를 읽어 정수 값 반환
    float readFloat() 4바이트를 읽어 실수 값 반환
    double readDouble() 8바이트를 읽어 실수 값 반환
    String readUTF() 수정된 UTF-8 인코딩 기반으로 문자열을 읽어 반환

    ※ 파일이든 네트워크든 자료를 쓸 때 사용한 메소드 순서대로 읽어야 함


    DataOutputStream 메소드

    자료형을 그대로 쓰는 스트림이기 때문에 같은 정수라도 자료형에 따라 다르게 처리

    메소드 설명
    void writeByte(int v) 1바이트 자료 출력
    void writeBoolean(boolean v) 1바이트 값 출력
    void writeChar(int v) 2바이트 출력
    void writeShort(int v) 2바이트 출력
    void writeInt(int v) 4바이트 출력
    void writeLong(long v) 8바이트 출력
    void writeFloat(float v) 4바이트 출력
    void writeDouble(double v) 8바이트 출력
    void writeUTF(String str) 수정된 UTF-8 인코딩 기반으로 문자열 출력

    예제_DataInputStream & DataOutputStream

    package j200206;
    
    import java.io.*;
    
    public class DataInOut2 {
    
        public static void main(String[] args) throws Exception {
    
            // 파일 저장
            File f = new File("c:/webtest/3.java/data.txt");
            FileOutputStream fos = new FileOutputStream(f);
    
            // 자바의 자료형에 맞게 출력 하도록 보조 스트림 생성
            DataOutputStream dos = new DataOutputStream(fos);
    
            // 메모리의 자료형에 맞게 저장
            char han = '한';
            byte b = 21;
            String str = "bg\n"; 		// \n : 줄바꿈
            byte ba[] = { 65, 66, 67 }; 	// A, B, C 변환
    
            // DataOutputStream 메소드를 사용해서 데이터 출력
            dos.writeChar(han);
            dos.writeByte(b);
            dos.writeBytes(str);
            dos.write(ba);
    
            // 파일에 자료 출력 후 스트림 메모리 해제
            dos.close();
            fos.close();
    
            // 자바의 자료형에 맞게 파일의 자료를 읽어오는 객체 생성
            DataInputStream dis = new DataInputStream(new FileInputStream(f));
    
            // 불러온 값을 새로운 변수에 저장
            char c = dis.readChar();
            byte b2 = dis.readByte();
            String str2 = dis.readLine();
            byte bb[] = new byte[3];
            dis.read(bb);
    
            System.out.println("c: " + c);
            System.out.println("b2: " + b2);
            System.out.println("str2: " + str2);
            // 문자열을 byte[]로 반환, 주소값 출력
            System.out.println("str2: " + str2.getBytes());
            // 바이트 배열 주소값 출력
            System.out.println("bb: " + bb);
            // byte[]를 매개변수로 하는 생성자를 사용해서 String으로 출력
            System.out.println(new String(bb));
    
            /*
            c: 한
            b2: 21
            str2: bg
            str2: [B@15db9742
            bb: [B@6d06d69c
            ABC
            */
    
        }
    
    }
    

    ※ DataInputStream readLine() 메소드
    DataInputStream의 readLine()은 더 이상 지원하지 않는(deprecated) 메소드이며,
    BufferedReader 클래스의 readLine() 메소드를 쓰도록 장려됨

     

    ※ getBytes(): String 클래스 일반 메소드, 문자열을 byte[]로 반환

     

    ※ String 클래스의 다양한 생성자를 이용한 String 객체(문자열) 생성 가능


    파일을 직접 읽거나 쓰지는 않지만 다양한 보조 기능을 제공하는 보조 스트림에 대해 알아보았습니다.

    한글이 깨지지 않도록 해주거나, 데이터 전송 속도를 높여주거나, 자바의 자료형 그대로를 입출력할 수 있도록 하는
    중요한 기능을 많이 제공하고 있기 때문에 알아 둘 필요가 있겠습니다.

    보조 스트림은 기반 스트림 하나에 여러 개를 사용할 수 있으며,

    보조 스트림 상위 클래스 FilterInput/OutputStream 의 이름에 맞게 데이터를 가공하는 역할을 한다고 볼 수 있습니다.

    'JAVA > JAVA' 카테고리의 다른 글

    Java | I/O File Class  (0) 2020.02.07
    Java | Serialization 직렬화  (0) 2020.02.07
    Java | I/O 문자 단위 스트림  (0) 2020.02.06
    Java | I/O 바이트 단위 스트림  (0) 2020.02.06
    Java | I/O 표준 입출력  (0) 2020.02.06

    댓글

Designed by Tistory.