우리는 일상속에서 스트림(Stream)이라는 단어를 정말 많이 들어봤을 것이다.
유튜브와 같은 라이브&비디오 스트리밍 사이트, 넷플릭스와 같은 비디오 스트리밍 사이트, 스포티파이와 같은 음악 스트리밍 사이트 등등 정말 많은 곳에서 스트림(Stream)이라는 용어를 사용한다.
물론 프로그래밍 언어상에서도 스트림이라는 단어를 자주 볼 수 있다. 입출력 관련된 내용을 다룰 때 꼭 한번씩은 봤던 기억이 난다. 스트림의 큰 맥락을 이해하면 앞으로 공부를 할 때 좀 더 수월하게 이해할 수 있을 것 같아 정리해두기로 했다. 🤗
1. 스트림(Stream)이란?
우선, 영단어 Stream의 뜻을 알면 좀 더 이해하기 쉬워진다.
Stream
(명사) 1. 개울, 시내 2.(액체 기체의) 줄기
(동사) 1. 줄줄[계속] 흐르다 2. 줄을 지어[줄줄이] 이어지다
Stream의 뜻 중 "줄줄이 이어지다"의 뜻이 일반적으로 컴퓨팅에서 사용하는 스트림의 언어와 비슷하다. 일반적으로 스트림이란 일련의 연속성을 갖는 흐름을 의미한다.
스트림의 동작에 대해 좀 더 쉽게 이해하기 위해 동영상을 예로 들어보자.
우리가 유튜브와 같은 사이트에서 영상을 클릭하면 서버에서 그 영상에 해당하는 영상 파일을 우리 컴퓨터로 보낼 것이다. 이때 서버에서 영상 파일을 통째로 보내게 된다면 파일이 모두 보내질때까지 우리는 그저 까만 화면만 봐야할 것이다. 이런 답답한 상황을 해결하기 위해 영상 파일을 잘게 쪼개 연속적으로 줄지어 우리 컴퓨터로 보내는 것이다. 그러면 우리는 먼저 도착한 쪼개진 영상 파일을 통해 기다림 없이 바로 영상을 볼 수 있게 되는 것이다. 줄줄이 연속적으로 흘러가는것 이것이 스트림의 동작 방식이다.
2. 컴퓨팅에서의 스트림(Stream)
위에서 설명한 것처럼 스트림은 일련의 연속성을 갖는 흐름을 뜻하는 것으로 매우 추상적인 개념이다. 그렇기 때문에 언어별로 스트림이 어떻게 쓰이는지를 알아보고 그것의 공통점을 찾아보면 스트림에 대한 이해도를 높일 수 있을 것이다.
▶ C/C++에서의 스트림 : 표준 스트림(standard stream)
: 표준 스트림이란 컴퓨터 프로그램과 그 환경(단말기) 사이에 미리 연결된 입출력 통로를 의미한다. 쉽게 말해 프로그램이 키보드 등을 통해 입력을 받고 프로그램에서 나름의 계산 후 결과값을 모니터에 출력하는 그 통로를 의미한다. 표준 스트림에 대해서 자세한 정리는 이후에 따로 포스팅 할 기회가 생기면 하겠다. 아무튼 C언어에서 스트림은 결국 프로그램을 드나드는 데이터, 파일 등을 바이트의 흐름으로 나타냈다고 볼 수 있다.
▶ JAVA에서의 스트림 1 : 입력/출력 스트림(Input/Output Stream)
: 입력/출력 스트림이란 표준 스트림과 비슷한 개념으로 프로그램이 출발지냐 또는 도착지냐에 따라서 스트림의 종류가 결정된다. 즉 프로그램이 데이터를 입력 받을 땐 입력 스트림을 이용하며 프로그램이 어디로 데이터를 보낼때는 출력 스트림을 이용한다. 여기에서 스트림 역시 프로그램을 드나드는 데이터, 파일 등의 바이트 흐름이라 볼 수 있다. 좀 독특한 것은 오로지 문자만 주고받을 수 있게 문자 단위 입출력 스트림이 존재한다는 것이다. BufferedReader / BufferedWriter이 그예이다. 이후 버퍼 개념 포스팅에서 다룰 생각이다.
▶ JAVA에서의 스트림 2 : 반복자 스트림(Stream)
: 자바8부터 추가된 반복자로 컬렉션, 배열 등의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 해주는 기능이다. 쉽게 말해 이전에는 컬렉션이나 배열 등의 원소를 가공할 때 for, foreach 등을 반복자를 통해서 각각의 원소에 접근해 원소를 가공하였지만 스트림의 경우 특정 타입의 스트림을 선언하여 필요한 형태로 가공하여 반환하게 된다. 이 개념 역시 이후에 따로 포스팅을 할 생각이다. 즉 여기에서 스트림이란 스트림의 선언부를 보면 이해하기 쉽다. 한 예로 Stream<int> stream = Arrays.stream(배열명); 를 들어보면 여기서 스트림이란 배열 형태의 int형 데이터의 흐름이라고 볼 수 있다.
▶ NodeJS에서의 스트림 : 스트림(Stream) 모듈
: 노드 공식 문서에서 스트림을 스트리밍 데이터로 작업하기 위한 추상적인 인터페이스라고 정의했다. 지금까지 정의된 Stream 중에서 제일 모호하다. 자바의 입력 출력 스트림과 비슷하게 읽기, 쓰기의 목적에 따라 Readable / Writable 스트림이 있다. 스트림 모듈의 동작 방식은 이후에 따로 정리하도록 하고 여기서의 스트림은 파일 접근이나 HTTP 요청으로 데이터를 읽을 때 등 정말 많은 부분에서 사용되는데 역시 특정 데이터의 흐름이라고 볼 수 있다.
결론적으로, 스트림이란 간단하게 말해서 데이터의 흐름으로 해석할 수 있다. 그 이후에 각각의 언어에 따라 사용하는 방식이 다르고 다루는 데이터 타입이 다르거나 사용 목적이 다르다 등 세부적인 사항들의 차이점을 가진다. 하지만 결국엔 데이터의 흐름이라는 공통점을 가지고 있는 것을 볼 수 있다. 앞으로 프로그래밍 공부하다 스트림 개념을 공부하게 되면 기본적으로 데이터의 흐름이라는 것을 염두해두고 공부하면 좀 더 수월하게 접근할 수 있지 않을까 생각해본다.