티스토리 뷰

BackEnd/Java&Kotilin

[Java] Java I/O

Hero_O 2022. 10. 1. 23:40

자바 IO

자바 애플리케이션의 입•출력 작업을 의미한다. java.io 패키지의 클래스를 사용하여 작업할 수 있다.
java.io 패키지는 크게 바이트 스트림 클래스와 문자 스트림 클래스 로 나뉜다.

 

네이밍에 따른 특성

  • Stream 으로 끝나는 클래스
    • 바이트 단위 IO
  • Reader 로 끝나는 클래스
    • 문자 단위 Input 클래스
  • Writer 로 끝나는 클래스
    • 문자 단위로 출력하는 클래스
  • File 로 시작하는 경우
    • 파일을 입출력 하는 클래스
  • ByteArray 로 시작
    • 바이트 배열을 읽거나 출력하는 클래스
  • CharArray로 시작
    • 문자 배열을 읽거나 출력하는 클래스
  • Filter로 시작
    • 상속을 통해 구현해 필터링 목적으로 커스텀해 사용
  • Data로 시작
    • 다양한 데이터 형식을 입출력 하는데 사용. 특히 기본형(primitive) 를 출력하는데 유리
  • Buffered로 시작
    • 버퍼링을 제공하는 IO 클래스
  • RandomAccessFile
    • 입 출력 모두하는 클래스로, 파일에서 임의 위치 내용을 읽거나 쓸 수 있는 기능 제공

 

 

바이트 스트림

바이트 IO 클래스

🔥 모든 바이트 스트림 클래스는 최상위 추상 클래스인 InputStream, OutputStream 에 하위 클래스이다. 따라서 모든 바이트 스트림은 InputStream, OutputStream 에 메소드를 포함한다.

public class BufferInputTest {  

  public static void main(String[] args) {  

    try (  
        BufferedInputStream inputStream = new BufferedInputStream(System.in);  
        BufferedOutputStream outputStream = new BufferedOutputStream(System.out)  
    ) {  
      byte[] buf = new byte[5];  
      int read = inputStream.read(buf);  
      outputStream.write(buf);  
    } catch (IOException e) {  
      throw new RuntimeException(e);  
    }  

  }  

}

주요 바이트 스트림

  • DataInputStream, DataOutputStream
    • 기본형 데이터를 읽고 쓰는데 사용된다.
  • ByteArrayInputStream , ByteArrayOutputStream
    • 바이트 배열로 데이터를 읽고 쓴다.
  • PipedInputStream, PipedOutputStream
    • Linux/Unix 에 파이프 (|) 기호처럼 서로다른 스레드에 데이터를 쓰고 읽는다.

문자 스트림

🔥 문자 IO 는 Reader, Writer의 서브 클래스로 이루어져 있다. 사용법은 바이트 스트림에 InputStream, OutputStream 과 비슷하다. 다만 바이트가 아닌 문자 단위로 읽고 쓴다.

public class StreamReaderTest {  

  public static void main(String[] args) {  
    InputStreamReader reader = new InputStreamReader(System.in);  
    OutputStreamWriter writer = new OutputStreamWriter(System.out);  
    try {  
      char[] chars = new char[10];  
      int read = reader.read(chars);  
      writer.write(chars);  
    } catch (IOException e) {  
      throw new RuntimeException(e);  
    }  
  }  

}

주요 문자 스트림

  • InputStreamReader, OutputStreamReader
      - `Reader` 와 `Writer` 에 상속을 받은 서브 클래스로 인스턴스화 가능하다. 내부 에서는 `InputStream`, `OutputStream` 을 통해 바이트 -> 문자 또는 문자 -> 바이트로 변형해 읽고 쓴다.
  • BufferedReader , BufferedWriter
    • 버퍼를 가지고 읽고 쓴다. 중간에서 버퍼링을 통해 성능 효율을 높여준다.
  • CharArrayReader , CharArrayWriter
    • 문자 배열을 통해 읽고 쓴다.

 

객체 스트림

jackson 라이브러리는 Obejct 를 바이트로 직렬화하고 반대로 문자열로 역직렬화 한다. 이처럼 객체를 직렬화하여 이동 시킬 수 있도록 해주는 스트림을 객체 스트림이라고 한다.

ObjectInputStream, OubjectOutputStream 을 통해 객체 I/O 가 가능하다.

특징

  • 💡 마샬링 하고 싶지 않은 필드 지정
    • transient 키워드를 통해 직렬화(마샬링) 하지 않을 필드 지정이 가능하다.
  • Serializable 를 구현한 클래스만 마샬링이 가능하다.
  • 마샬링
    • 데이터를 바이트의 흐름으로 만들어 TCP와 같은 통신 채널을 통해서 전송하거나 스트림으로 써줄 수 있는 형태로 변환하는 과정 사실상 객체 직렬화는 마샬링과 같은 의미라고 볼 수 있다.
  • 언마샬링
    • 마샬리의 반대로 전송받은 데이터를 원래의 형태로 변화하는 것을 의미한다.

예시

  • Book
public class Book implements Serializable {
  private String title;
  transient private String isbn;
  private String author;

  public Book() {}

  public Book(String title, String isbn, String author) {
    this.title = title;
    this.isbn = isbn;
    this.author = author;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getIsbn() {
    return isbn;
  }

  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  @Override
  public String toString() {
    return "Book{" +
        "title='" + title + '\'' +
        ", isbn='" + isbn + '\'' +
        ", author='" + author + '\'' +
        '}';
  }
}

 

 

  • ObjectInputStream , ObjectOutputStream
public class ObjectStreamTest {

  public static void main(String[] args) {
    try(
        FileOutputStream fout = new FileOutputStream("book.dat");
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        )
    {
      Book book = new Book("리팩터링2판", "1245-2412-3123","마틴 파울러");
      oos.writeObject(book);
      oos.reset();
      System.out.println("저장 완료");
    } catch (FileNotFoundException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    try (
        FileInputStream fis = new FileInputStream("book.dat");
        ObjectInputStream ois = new ObjectInputStream(fis);
    ) {
      Book book =(Book)ois.readObject();
      System.out.println(book);
    } catch (FileNotFoundException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }

  }

}

 

    결과
    저장 완료
    Book{title='리팩터링2판', isbn='null', author='마틴 파울러'}

 

 

참고

 

 

댓글