Java에서의 입출력
사용자가 키보드로 입력한 문자를 받아와 모니터에 보여주려면 어떻게 해야할까?
만약 사용자가 특정 문서를 인쇄하기 위해 인쇄 버튼을 누른다면 이를 프린터를 어떻게 인쇄할까?
이처럼 프로그램에서 데이터를 받아오거나 데이터를 특정 장치에 보내줘야 할 때, 바로 스트림을 이용한다.
위의 경우에서는 키보드로 입력한 문자를 받아올 때 입력 스트림을, 해당 문자를 화면에 나타낼 때 출력 스트림을 이용한다.
또 사용자가 인쇄를 요청한 경우에는 인쇄를 담당하는 프로그램이 해당 문서의 내용을 입력 스트림을 통해 받아오며, 출력 스트림을 통해 프린터기로 데이터를 전송한다.
스트림이란 데이터를 교환하려는 두 대상을 연결하고, 데이터를 전송할 수 있는 통로 역할을 한다.
Stream의 특징
단방향통신
스트림은 연속적인 데이터의 흐름을 냇물, 흑 흐르는 물에 비유해서 붙여진 이름이다.
냇가의 물이 한쪽 방향으로만 흐르는 것처럼, 스트림도 오직 단방향통신만 가능하다.
하나의 스트림에 의해 연결된 두 대상이 있을 때, '어떤 대상이' '입/출력'을 수행한다.
일단 하나의 스트림이 생성되고 나면, '입/출력' 중 어떤 것을 수행하는 지와 그 작업을 '어떤 대상이' 수행하는지를 변경할 수 없다는 뜻이다.
입출력을 모두 수행하고 싶다면 입력 스트림과 출력 스트림 두 개를 모두 만들어야 한다.
FIFO의 구조
입력 스트림의 경우 먼저 전송되어 들어온 데이터가 그대로 프로그램에 전달되는 FIFO 구조를 띄고 있다. 중간에 건너뜀 없이 연속적으로 데이터를 주고받는다.
출력 스트림의 경우 역시 프로그램에서 먼저 출력하는 순서대로 전달된다.
[ 바이트기반 스트림 - InputStream, OutputStream ]
스트림은 바이트단위(1byte)로 데이터를 전송하며 입출력 대상에 따라 사용할 수 있는 스트림 종류가 나뉘어져 있는데, 이들은 모두 InputStream과 OutputStream을 구현한 자손들이다.
입력스트림 | 출력스트림 | 입출력 대상 종류 |
FileInputStream | FileOutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리 |
PipedInputStream | PipedOutputStream | 프로세스 |
AudioInputStream | AudioOutputStream | 오디오 장치 |
InputStream과 OutputStream은 각각 read와 write 라는 추상메서드를 가진다.
모든 자손 스트림들은 입출력 대상에 맞게 위 추상메서드를 알맞게 구현하여 사용한다.
보조 스트림
실제로 데이터를 주고받는 역할은 하지 않지만, 스트림의 기능을 향상시키거나 새로운 기능을 추가해주는 스트림이다.
보조스트림만으로는 입출력을 처리할 수 없다. 반드시 기반 스트림을 먼저 생성한 다음 이를 이용하여 보조스트림을 생성하여야 한다.
아래와 같이 사용한다.
// 기반 스트림을 먼저 생성한다.
FileInputStream fis = new FileInputStream("test.txt");
// 기반 스트림을 바탕으로 보조 스트림을 생성한다. (= 보조 스트림에 입출력을 수행해줄 기반 스트림을 등록)
BufferedInputStream bis = new BufferedInputStream(fis);
// 보조 스트림을 이용하여 데이터를 읽는다.
bis.read();
보조 스트림 역시 InputStream과 OutputStream을 구현한 자손들이다. 즉, 입출력 방법(메서드)이 기반 스트림과 같다.
입력 | 출력 | 설명 |
FilterInputStream | FilterOutputStream | 필터를 이용한 입출력 처리 (모든 보조스트림의 조상) |
BufferedInputStream | BufferedOutputStream | 버퍼를 이용한 입출력 성능향상 |
DataInputStream | DataOutputStream | int, float 등 기본형 단위로 데이터를 처리하는 기능 |
없음 | PrintStream | 버퍼를 이용, 추가적인 print 관련 기능 (print,printf,println) |
etc ... |
[ 문자기반 스트림 - Reader, Writer ]
바이트기반 스트림은 1btye 단위로 데이터를 읽어오고, 출력한다.
Java의 char은 2byte이기 떄문에 바이트단위 스트림으로는 문자를 처리하는 데 어려움이 있으므로 2byte 단위의 문자기반 스트림을 제공한다. 이들은 InputStream, OutStream 대신 Reader, Writer를 구현한 자손 스트림이다.
바이트기반 스트림 | 문자기반 스트림 | 입출력 대상 종류 |
FileInputStream FileOutputStream |
FileReader FileWriter |
파일 |
ByteArrayInputStream ByteArrayOutputStream |
CharArrayReader CharArrayWriter |
메모리 (char배열) |
PipedInputStream PipedOutputStream |
PipedReader PipedWriter |
프로세스 |
(deprecated) StringBufferInputStream StringBufferOutputStream |
StringReader StringWriter |
메모리 (String) |
* StringBufferInputStream, StringBufferOutputStream는 더이상 사용하지 않는다.
Reader와 Writer 역시 각 read, write 라는 추상메서드를 가지며, 각 스트림은 이 메서드를 구현하여 입출력을 수행한다.
보조스트림
문자기반 스트림 역시 보조스트림을 가진다. 사용목적과 방식은 바이트기반 보조스트림과 다르지 않다.
바이트기반 보조스트림 | 문자기반 보조스트림 |
BufferedInputStream BufferedOutputStream |
BufferedReader BufferedWriter |
FilterInputStream FilterOutputStream |
FilterReader FilterWriter |
PrintStream | PrintWriter |
'프로그래밍 언어 > Java' 카테고리의 다른 글
Java의 예외처리 (함수 너 회피형이야?) (1) | 2025.01.02 |
---|---|
잠깐 ! JVM 정리하고 갑시다 (1) | 2024.12.31 |
[Java] 문자열(String) 내장 함수 정리 (1) | 2024.01.11 |
[Java] CharSequence란? (0) | 2024.01.11 |
[Java] 문자열(String) 클래스 정리 (0) | 2024.01.11 |