키워드
개울, 고속도로, 흐른다, 단방향, 선입선출, 연결, 통신, 바이트 스트림, 보조 스트림 , 스트링 스트림
입출력?
컴퓨터 내부 또는 외부의 장치와 프로그램 간에 데이터를 주고 받는 것.
Input/Output 으로 입력/출력을 이야기한다. 줄여서, I/O
스트림이란?
자바에서 입출력 스트림은 데이터의 흐름을 다루는데 사용된다.
각 끝점의 연결 통로이다.
데이터의 흐름을 다룬다
-> 영어로 Stream은 흐르다 라는 뜻의 영어동사 이다. 구글에 Stream을 검색하면 개울 이미지가 나온다.
-> 개울에는 물이 흐른다. 컴퓨터 세상에는 데이터가 흐른다.
물은 흐를 때 위에서 아래로 흐른다. -> 흐름의 방향이 정해져있다. -> 스트림도 흐름의 방향이 정해져있다.
스트림의 특징
- 스트림은 단방향이다. 한쪽 방향으로만 흐를 수 있다.
( 고속도로에 한번 올라타면 그대로 한방향으로 가야한다. 역주행할 수 없다.) - 하나의 스트림은 하나의 역할을 한다
( 고속도로는 목적지로 가기 위해서 주행 차선과 반대 차선 이렇게 나뉘어져있다. 즉, 입력과 출력을 위해서는 각각의 스트림이 필요하다.) - 스트림은 선입선출 , FIFO 구조이다.
First In First Out, 먼저 들어온게 먼저 나간다. - 스트림은 여러개가 연결될 수 있다.
-> 키보드에서 문자를 입력 받는 System.in과 바이트 단위로 읽는 형식을 문자 단위로 변환시켜주는 InputStreamReader를 연결할 수 있다. (new InputStreamReader(System.in)) - 스트림은 지연될 수 있다.
-> 입력 스트림이 비어 있으면, 컴퓨터는 읽을 데이터가 없으므로 기다린다.
-> 출력 스트림이 꽉 차 있으면, 컴퓨터는 빈 공간이 생길 때 까지 기다린다.
스트림의 종류
1. 바이트 스트림 (InputStream, OutputStream)
스트림은 바이트 단위로 데이터를 전송하며 입출력 대상에 따라 여러가지의 입출력 스트림이 있다.
기본 클래스로 InputStream과 OutputStream이 있으며, 입출력 대상에 따라 여러 가지 자식들을 가지고 있다.
- 파일 : FileInputStream, FileOutputStream
- 메모리 : ByteArrayInputStream, ByteArrayOutputStream
- 프로세스간의 통신: PipedInputStream, PipeOutputStream
- 오디오장치: AudioInputStream, AudioOutputStream
1.1. 보조 스트림
실제 데이터를 주고 받는 스트림은 아니기 때문에, 데이터를 입출력 할 수 있는 기능은 없지만 스트림의 기능을 향상시키거나 새로운 기능을 추가할 수 있다.
-> 아까 스트림의 특징이 기억나나? 스트림은 여러개가 연결될 수 있다. 입출력을 기능을 할 수 있는 스트림과 기능을 향상시키는 보조스트림을 "연결" 하여서 성능을 향상 시켜 사용할 수 있다.
예를 들어, text 파일을 읽기 위해 FileInputStream을 사용할 떄, 입력 성능을 향상시키기 위해 버퍼를 사용하는 보조스트림인 BufferedInputStream을 사용한다.
// 기반스트림을 바탕으로 보조스트림 연결
BufferedInputStream bis = BufferedInputStream(new FileInputStream("test.txt"))
//보조스트림으로부터 데이터를 읽는다.
bis.read()
실제 입력기능은 바이트 스트림인 FileInputStream 이 수행하고, 보조 스트림인 BufferedInputStream은 버퍼만을 제공한다. 버퍼를 사용한 입출력과 사용하지 않은 입출력은 성능차이가 상당하기 때문에 대부분의 경우에 버퍼를 이용한 보조스트림을 사용한다.
- 버퍼를 이용한 입출력 성능향상 : BuffredInputStream, BufferedOutputStream
- 필터를 이용한 입출력 처리 : FilterInputStream, FilterOutputStream
- 데이터를 객체 단위로 입출력 할 때 사용. 객체의 직렬화 때 사용 : ObjectInputStream, ObjectOutputStream
2. 문자기반 스트림 (Reader, Writer)
컴퓨터의 모든 데이터는 바이트 단위 데이터로 구성되어있다. -> 데이터의 입출력은 바이트 단위로 저장된다.
InputStream 또한 바이트 단위로 데이터를 보낸다. 입력 메소드인 read()는 1 바이트 단위로 읽어들인다.
1바이트 이상의 데이터는 나머지는 읽지않고 스트림에 남아잇다.
자바에서는 한 문자를 의미하는 char 형이 1byte가 아니라 2byte 이다. 한글은 3byte다.
1byte만 인식하면, 정상적인 값을 전달받을 수 없게 된다.
문자를 온전히 받기 위해서 InputStreamReader. 즉, 문자기반 스트림이 필요하다.
정리
가장 앞서 작성했던 키워드를 기반으로 정리를 해보자.
스트림은 데이터의 흐름이다. 개울의 물이 흐르는것 처럼 데이터 또한 스트림을 통해 흐른다. 또 스트림은 고속도로처럼 주행 차선과 반대 차선이 나눠져 있다. 흐름은 단방향으로만 갈 수 있기 때문에, 입력과 출력 각각 다른 스트림이 필요하다.
통신은 기본적으로 바이트 단위로 데이터를 주고 받는다. 바이트를 입출력 받기 위해서는 바이트 스트림이 필요하고, 바이트 스트림에 추가적인 성능 향상이나 기능 추가를 위해서는 보조스트림을 연결 한다. 바이트 스트림은 1 바이트 단위로 데이터를 주고 받기 때문에, 문자 데이터는 정상적으로 값을 받을 수 없다.그래서 값을 정상적으로 인식하기 위해 문자기반 스트림을 이용한다.
'JAVA' 카테고리의 다른 글
[JAVA] Socket이란? 개념부터 흐름까지 (+ HTTP 통신과의 차이점, 코드 포함) (1) | 2024.03.08 |
---|