본문 바로가기

JAVA

입출력 I/O - 바이트 기반 스트림

I/O : Input, Output의 약자

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

ex) 키보드에서 데이터 입력받기, System.out.println()으로 화면에 출력하기 등등..

 

I/O에서 다루는 Stream은 람다와 스트림에서 다루는 그 Stream()과 다르다

Stream : 두 대상을 데이터를 전송할 수 있는, 데이터를 운반하는 데 사용하는 연결통로

Stream은 물이 한쪽 방향으로 흐르는것과 같이 데이터를 전송할 때 단방향통신만 가능하기 때문에 하나의

Stream으로 입력과 출력을 동시에 할 수 없다.

 

그래서 입력과 출력을 동시에 수행하려면

입력을 위한 입력스트림(input Stream),

출력을 위한 출력스트림(output Stream) 총 2개가 필요하다.

 

Stream은 먼저 보낸 데이터를 먼저 받게 되어 있으며, 중간에 건너뛰는 것 없이 연속적으로 데이터를 주고받는다.

 

 

바이트 기반 스트림 - InputStream, OutputStream

Stream은 byte단위로 데이터를 전송하며 입출력 대상에 따라 입출력 스트림이 다르다.

 

입력스트림 : FileInputStream, ByteArrayInputStream, PipedInputStream, AudioInputStream

출력스트림 : FileOutputStream, ByteArrayOutputStream, PipedInputStream, AudioOutputStream

각각 파일, 메모리(byte배열), 프로세스, 오디오장치를 입출력한다.

 

파일의 내용을 읽을땐 FileInputStream, 파일의 내용을 불러올땐 FileOutputStream을 쓴다.

 

입출력관련 클래스들

InputStream : read

abstract int read() - > abstract니까 추상메서드, 입력스트림으로부터 1 byte를 읽어서 반환하고 읽을 수 없으면 -1 반환

int read(byte[] b)

int read(byte[] b, int off, int len) - > 입력스트림으로부터 len크기의 byte를 읽어서 byte배열인 b의 off위치부터 저장함

 * read의 반환타입이 int인 이유는 read()의 반환범위가 0~255, 그리고 -1라서

 

OutputStream : write

abstract void write(int b)

void write(byte[] b)

void write(byte[] b, int off, int len)

 

입출력의 대상에 따라 읽고 쓰는 방법이 다르기 때문에 추상메서드도 정의되어 있다.

 

 

2025 - 06 - 14

InputStream, OutputStream에서 사용하는 메서드

둘 다 바이트 기반 스트림의 조상이며 사용하는 메서드가 다르다.

 

InputStream에서 사용하는 메서드

int available() : 스트림으로부터 읽어올 수 있는 데이터의 크기를 반환함

void close() : 스트림을 닫아서 사용하고 있던 자원을 반환함

void mark(int readlimit) : 현재 위치?를 표시해둠. 후에 reset()을 써서 표시해놓은 위치로 돌아갈 수 있음. 인자는 되돌아갈 수 있는 byte의 수라고 

boolean markSupported() : mark(), reset()을 지원하는지 알려줌. 이는 선택적이므로 markSupported()로 확인해야함

abstract int read() : 1byte를 읽어옴. 읽어올 데이터가 없으면 -1를 반환함.  abstract라서 inputStream의 자손들은 상황에 맞게 구현해야한다

int read(byte[] b) : 배열 b 크기만큼 읽은 뒤 배열을 채우고 읽어온 데이터의 수를 반환한다. 반환값은 항상 배열의 크기보다 작거나 같음

int read(byte[] b, int off, int len) : 최대 len개의 byte를 읽어서 배열 b의 지정된 위치(off)부터 저장함. 배열 b를 off부터 len개만큼 읽어온다. 실제로 읽어올 수 있는 데이터는 len개보다 적을 수 있음

void reset() : 스트림에서의 위치를 마지막으로 mark()이 호출되었던 위치로 되돌림

long skip(long n) : 스트림에서 주어진 길이(n)만큼 건너뜀

 

 

OutputStream에서 사용하는 메서드

void close() : 입력소스를 닫아서 사용하고 있던 자원 반환

void flush() : 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다

abstract void write(int b) : 주어진 값을 출력소스에 쓴다

void write(byte[] b) : 주어진 배열 b에 저장된 모든 내용을 출력소스에 씀

void write(byte[] b, int off, int len) : 주어진 배열 b에 저장된 내용 중 off번째부터 len개만큼 읽어서 출력소스에 씀

 

정리 : inputStream에선 read(), OutputStream에선 write()를 쓰면 됨

 

* flush()는 버퍼가 있는 출력스트림의 경우에만 의미있으면 그냥 OutputStream에 정의된 flush()는 아무런 일도 하지 않음

* 일반적으로 스트림을 사용한 뒤 close()를 호출해서 닫아줘야하지만, ByteArrayInputStream과 같은 메모리 스트림과

System.in, System.out과 같은 표준 입출력 스트림은 닫지 않아도 된다.

 

 

'JAVA' 카테고리의 다른 글

기본적인 File I/O에 대한 이해  (1) 2025.06.13
I/O - 보조 스트림  (0) 2025.06.13
객체 직렬화 / 역직렬화  (1) 2025.06.10
Stram API의 map과 flatMap의 차이점  (0) 2025.06.08
단일 책임 원칙(SRP)과 개방-폐쇄 원칙(OCP)  (0) 2025.06.05