[자바의 정석]I/O

YJS·2023년 12월 13일
0

1. 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O


입출력이란?

IO = Input과 Output의 약자

컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는것

1) 스트림

데이터를 운반하는데 사용되는 연결통로

단방향 통신만 가능. = 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없음.

큐와 같은 구조(선입선출)

2)버퍼

보조스트림은 실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 있는 기능은 없으나 스트림의 기능을 향상시키거나 새로운 기능 추가 가능.

→ 따라서 스트림을 먼저 생성한 다음에 보조스트림 생성해야함

→모든 보조 스트림 역시 InputStream 과 OutputStream의 자손임

입력출력설명
FileInputStreamFileOutputStream필터를 이용한 입출력 처리
BufferedInputStreamBufferedOutputStream버퍼를 이용한 입출력 성능향상
DataInputStreamDataOutputStreamint, float와 같은 기본형 단위로 데이터를 처리하는 기능
SequenceInputStream없음두개의 스트림을 하나로 연결
LineNumberInputStream없음읽어 온 데이터의 라인 번호를 카운트
ObjectInputStreamObjectOutputStream데이터를 객체단위로 읽고 쓰는데 사용
없음PrintStream버퍼를 이용하며, 추가적인 print 관련 기능(print, printf, println)
PushbackInputStream없음버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능(unread, push back to buffer)

3)채널

데이터가 통과하는 쌍방향 통로

→ 채널에서 데이터를 주고 받을 때 사용 되는 것이 버퍼

→ 채널에는 소켓과 연결된 SocketChannel, 파일과 연결된 FileChannel, 파이프와 연결된 Pipe.SinkChannel 과 Pipe.SourceChannel 등이 존재하며, 서버소켓과 연결된 ServerSocketChannel 도 존재

2. InputStream과 OutputStream


스트림은 바이트단위로 데이터를 전송

입력스트림출력스트림입출력 대상의 종류
FileInputStreamFileOutputStream파일
ByteArrayInputStreamByteArrayOutputStream메모리(byte배열)
PipedInputStreamPipedOutputStream프로세스(프로세스간의 통신)
AudioInputStreamAudioOutputStream오디오장치

java.io패키지를 통해 입출력 관련 클래스 제공

메서드를 통해서 데이터를 읽고 쓸 수 있음

e.g. int read(byte[]b, int off, int len) , void write(byte[]b, int off, int len)

= 입력스트림으로부터 len개의 byte를 읽어서 byte배열 b의 off위치부터 저장

( 추상클래스를(abstract class InputStream) 상속받아서 추상메서드를(abstract int read) 구현한 클래스의 인스턴스에 대해서 추상메서드가 호출되는 것이기 때문에 read()는 반드시 구현되어야하는 핵심적인 메서드임. 따라서 read()없이 int read(byte[]b, int off, int len)는 사용 불가.)

1)InputStream

  • 바이트 기반 입력 스트림의 최상위 추상 클래스
  • 모든 바이트 기반 입력 스트림은 이 클래스를 상속 받아서 만들어 짐
  • 버퍼, 파일, 네트워크 단에서 입력되는 데이터를 읽어오는 기능을 수행
메서드설명
read()입력 스트림으로부터 1바이트를 읽어서 바이트를 리턴
read(byte[] b)입력 스트림으로부터 읽은 바이트들을 매개값으로 주어진 바이트 배열 b 에 저장하고 실제로 읽은 바이트 수를 리턴
read(byte[] b, int off, int len)입력 스트림으로부터 len 개의 바이트만큼 읽고 매개값으로 주어진 바이트 배열 b[off] 부터 len 개까지 저장. 그리고 실제로 읽은 바이트 수인 len 개를 리턴. 만약 len 개를 모두 읽지 못하면 실제로 읽은 바이트 수를 리턴
close()사용한 시스템 자원을 반납하고 입력 스트림 닫기

1)OutputStream

  • 바이트 기반 출력 스트림의 최상위 추상 클래스
  • 모든 바이트 기반 출력 스트림은 이 클래스를 상속 받아서 만들어 짐
  • 버퍼, 파일, 네트워크 단으로 데이터를 내보내는 기능을 수행
메서드설명
write(int b)출력 스트림으로부터 1바이트를 보낸다.(b 의 끝 1바이트
write(byte[] b)출력 스트림으로부터 주어진 바이트 배열 b의 모든 바이트를 보낸다.
write(byte[ ] b, int off, int len)출력 스트림으로 주어진 바이트 배열 b[off] 부터 len 개까지의 바이트를 보낸다.
flush()버퍼에 잔류하는 모든 바이트를 출력한다.
close()사용한 시스템 자원을 반납하고 입력 스트림 닫기

3. Byte와 Character 스트림


Byte기반 스트림: 입출력의 단위가 1byte임.

(자바에서는 한 문자를 의미하는 char형이 1 byte가 아니라 2 byte이기 때문에 바이트기반의 스트림으로 2byte인 문자를 처리하는 데는 어려움이 있음. 이를 보완하기 위해 문자 기반의 스트림이 제공됨.)

InputStream → Reader

OutputStream → Writer

1) Byte Stream

  • binary 데이터를 입출력하는 스트림
  • 데이터는 1바이트 단위로 처리
  • 이미지, 동영상 등을 송수신 할 때 주로 사용

2) Character Stream

  • text 데이터를 입출력하는 스트림
  • 데이터는 2바이트 단위로 처리
  • 일반적인 텍스트 및 JSON, HTML 등을 송수신할 때 주로 사용

4. 표준 스트림 (System.in, System.out, System.err)


애너테이션에 대한 기본 정보가 javadoc으로 작성한 문서에 포함되도록함.

표준 입출력 스트림의 종류는 java.lang 패키지의 System 클래스 내부에 static 으로 선언되어 있음

public final class System {
  public static final InputStream in;
  public static final PrintStream out;
  public static final PrintStream err;
  ....
}

→ System.out 은 콘솔 화면에 문자열을 출력하기 위한 용도로 사용되는 출력 스트림이다.

→ System.in 은 키보드의 입력을 받아들이기 위해서 사용되는 입력 스트림이다.

cf. System.out 과 System.err

둘다 출력 스트림

→ err 은 버퍼링을 지원하지 않음. (err 이 보다 정확하고 빠르게 출력되어야 하기 때문) 버퍼링을 하던 도중 프로그램이 멈추면 버퍼링된 내용은 출력되지 않기 때문

5. 파일 읽고 쓰기


애노테이션 프로세서는 소스코드 레벨에서 소스코드에 붙어있음.

→ 텍스트 파일인 경우 문자 스트림 클래스들을 사용하면 되고, 바이너리 파일인 경우 바이트 스트림을 기본적으로 사용한다.

→ 입출력 효율을 위해 Buffered 계열의 보조 스트림을 함께 사용하는 것이 좋음.

  • 텍스트 파일인 경우
    BufferedReader br = new BufferedReader(new FileReader("a.txt"));
    BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
    String s;
    while ((s = br.readLine()) != null) {
      bw.write(s + "\n");
    }
  • 이진 파일인 경우
    BufferedInputStream is = new BufferedInputStream(new FileInputStream("a.jpg"));
    BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("b.jpg"));
    byte[] buffer = new byte[16384];
    while (is.read(buffer) != -1) {
      os.write(buffer);
    }
profile
우당탕탕 개발 일기

0개의 댓글