[프로그래머스 자바 중급] 입력과 출력 : 보조 스트림

2 분 소요

보조 스트림

  • 자바에서 제공하는 보조 스트림은 실제로 데이터를 주고받을 수는 없지만, 다른 스트림의 기능을 향상시키거나 새로운 기능을 추가해주는 스트림이다.

  • 자바에서는 다음과 같은 보조 스트림을 제공하고 있다.

    입력 스트림 출력 스트림 설명
    FilterInputStream FilterOutputStream 필터를 이용한 입출력
    BufferedInputStream BufferedOutputStream 버퍼를 이용한 입출력
    DataInputStream DataOutputStream 자바의 기본 자료형 데이터를 입출력할 수 있도록 한다
    ObjectInputStream ObjectOutputStream 스트림으로부터 객체를 입력(역직렬화)하거나, 객체를 스트림에 출력(직렬화)
    SequenceInputStream X 두 개의 입력 스트림을 논리적으로 연결
    PushbackInputStream X 다른 입력 스트림버퍼를 이용하여 push back이나 unread와 같은 기능을 추가
    X PrintStream 다른 출력 스트림버퍼를 이용하여 다양한 데이터를 출력하기 위한 기능을 추가
    • 직렬화(Serialization)
      • 객체를 데이터 스트림으로 바꾸는 것.
      • 즉, 객체에 저장된 데이터를 스트림에 쓰기(write) 위해 연속적인(serial) 데이터로 변환하는 것.
      • 객체를 상태 그대로 저장하거나 메모리, 데이터베이스 혹은 파일로 옮기기 위해 사용.
    • 역직렬화(Deserialization)
      • 네트워크나 영구저장소에서 스트림을 다시 객체로 변환하는 것. 자바에서의 직렬화 & 역직렬화

다양한 타입의 데이터 출력

  • 다양한 자바 기본 자료형 데이터를 저장할 수 있는 DataOutputStream
    • writeInt() : int 값으로 저장
    • writeBoolean() : boolean 값으로 저장
    • writeDouble() : double 값으로 저장
    import java.io.FileOutputStream;
    import java.io.DataOutputStream;
    
    public class ByteExam3 {
    
      public static void main(String[] args) {
        // try-with-resources 사용
        // io 객체 선언.
        try (DataOutputStream out = new DataOutputStream(new FileOutputStream("data.txt"));) {
          // io 객체 사용 후, 자동으로 자원이 종료된다.
          out.writeInt(100); // int 형(4 바이트) 데이터를 쓰기
          out.writeBoolean(true); // boolean 형(1 바이트) 데이터를 쓰기
          out.writeDouble(50.5); // double 형(8 바이트) 데이터를 쓰기
    
        } catch (Exception e) {
          e.printStackTrace();
        }
      }//--main()
    }//--class
    
    • DataOutputStream보조 스트림이므로 기반 스트림이 필요하며, FileOutputStream기반 스트림으로 사용했다.
      • FileOutputStream바이트 단위의 데이터만 출력할 수 있다.
      • 하지만, 보조 스트림DataOutputStream을 사용하여 자바 기본 자료형의 데이터를 출력할 수 있다.
    • 아래와 같이 DataOutputStream기본 자료형 데이터를 바이트 스트림으로 변환하여 출력을 수행한다. 따라서 출력한 데이터(바이트 스트림 형태)를 다시 읽어올 때는 DataInputStream으로 읽어 와야 한다.

      DataOutputStream과 DataInputStream

    • 💡 try-with-resources를 이용한 자원 종료
      • 자바 I/O 객체는 인스턴스를 만들고 모두 사용하면 close() 메소드를 호출하여 사용한 자원을 종료해야 한다.
      • try-with-resources를 사용하면 close() 메소드를 사용자가 호출하지 않더라도, try(...)에 선언된 객체들에 대해서 try 블럭이 종료될 때 자동으로 사용한 자원을 종료해준다.

        try ( // io 객체 선언) {
          // io 객체 사용
        } catch (Exception ex) {
          ex.printStackTrace();
        }
        
  • 실행 결과

    ByteExam3 실행결과 : 13 바이트의 data.txt 파일 생성

    • 13 바이트의 데이터가 써진 data.txt 파일이 생성되었다.

다양한 타입의 데이터 입력

  • 다양한 자바 기본 자료형 데이터를 읽어낼 수 있는 DataInputStream
    • readInt() : 스트림으로부터 읽은 int 값을 반환
    • readBoolean() : 스트림으로부터 읽은 boolean 값 반환
    • readDouble() : 스트림으로부터 읽은 double 값 반환
  • ex) data.txt로부터 값을 읽어 들여 콘솔에 출력

    import java.io.DataInputStream;
    import java.io.FileInputStream;
    
    public class ByteExam4 {
    
      public static void main(String[] args) {
        // try-with-resources
        // io 객체 선언
        try ( DataInputStream in = new DataInputStream(new FileInputStream("data.txt")); ) {
          // io 객체 사용 후, 자동으로 자원 종료
          int i = in.readInt(); // int 형(4 바이트) 데이터 읽기
          boolean b = in.readBoolean(); // boolean 형(1 바이트) 데이터 읽기
          double d = in.readDouble(); // double 형(8 바이트) 데이터 읽기
    
          System.out.println(i);
          System.out.println(b);
          System.out.println(d);
    
        } catch(Exception ex) {
          ex.printStackTrace();
        }
    
      }//--main()
    
    }//--class
    
    • 파일을 읽어 들이기 위해 기반 스트림으로 FileInputStream을 사용하고, 파일에서 읽어 들인 바이트 스트림자바 기본 자료형으로 읽어 들이기 위해 보조 스트림으로 DataInputStream을 사용했다.
    • 💡 각 자료형의 크기가 다르므로, 출력한 데이터를 다시 읽어 올 때는 파일에 출력한 순서대로 읽어 들여야 한다.
      • int, boolean, double 순서로 저장했기 때문에, 읽어 들일 때도 같은 순서로 읽어 들였다.
  • 실행 결과

    100
    true
    50.5
    
  • 이처럼 DataInputStreamDataOutputStream을 사용하면 특정 타입으로 데이터를 저장하고 불러올 수 있다.

출처