스트림의 개념을 설명 할 수 있습니까?


186

스트림은 바이트 시퀀스를 나타냅니다. 각 스트림은 주어진 백업 저장소에서 바이트를 읽고 쓰는 수단을 제공합니다. 그러나 시내의 요점은 무엇입니까? 백킹 스토어 자체가 우리가 상호 작용하는 것이 아닌 이유는 무엇입니까?

어떤 이유로 든이 개념은 나를 위해 클릭하지 않습니다. 나는 많은 기사를 읽었지만 비유 나 무언가가 필요하다고 생각합니다.

답변:


234

"스트림"이라는 단어는 (실제로) 사용할 때 전달하고자하는 것과 매우 유사한 의미를 나타 내기 때문에 선택되었습니다.

뒷받침 가게를 조금 잊고 물 흐름과의 비유에 대해 생각해 봅시다. 물이 강에 지속적으로 흐르는 것처럼 연속적인 데이터 흐름을받습니다. 데이터가 어디에서 오는지 반드시 알 필요는 없으며 대부분의 경우 필요하지 않습니다. 파일, 소켓 또는 다른 소스에서 가져온 것이 든 실제로 중요하지는 않습니다. 이것은 물의 흐름을받는 것과 매우 유사하므로 물의 출처를 알 필요가 없습니다. 호수, 분수대 또는 기타 다른 곳에서 나온 것이 든 실제로 중요하지는 않습니다.

즉, 데이터의 출처에 관계없이 필요한 데이터를 얻는 것에 만 관심이 있다고 생각하기 시작하면 다른 사람들이 이야기 한 추상화가 더 명확 해집니다. 스트림을 줄 바꿈 할 수 있다고 생각하기 시작하지만 메서드는 여전히 완벽하게 작동합니다. 예를 들어 다음과 같이 할 수 있습니다.

int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }

// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);

int x = ReadInt(reader);

보시다시피 처리 로직을 변경하지 않고 입력 소스를 변경하기가 매우 쉬워졌습니다. 예를 들어, 파일 대신 네트워크 소켓에서 데이터를 읽으려면 :

Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);

가능한 한 쉽게. 스트림 "래퍼"를 만들 수있는 한, 모든 종류의 입력 소스를 사용할 수 있기 때문에 아름다움은 계속됩니다. 당신은 이것을 할 수도 있습니다 :

public class RandomNumbersStreamReader : StreamReader {
    private Random random = new Random();

    public String ReadLine() { return random.Next().ToString(); }
}

// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());

보다? 메소드가 입력 소스를 신경 쓰지 않는 한 다양한 방법으로 소스를 사용자 정의 할 수 있습니다. 추상화를 통해 처리 논리에서 입력을 매우 우아한 방식으로 분리 할 수 ​​있습니다.

우리가 만든 스트림에는 백업 저장소가 없지만 여전히 우리의 목적에 완벽하게 부합합니다.

요약하자면, 스트림은 입력 소스 일 뿐이며 다른 소스를 숨기거나 제거합니다. 추상화를 중단하지 않는 한 코드는 매우 유연합니다.


6
추상적 인 생각 (그리고 설명)은 당신의 피 속에있는 것 같습니다.
java.is.for.desktop

@HosamAly 귀하의 설명은 매우 명확하지만 샘플 코드에서 약간 혼란스러워합니다. 문자열에서 int 로의 명시 적 변환은 ReadInt? 나도 ReadString을 할 수 있다고 생각합니까?
Rushino

1
@Rushino 위의 코드에는 변환이 없습니다. 이 메소드 ReadInt는를 사용하여 맨 위에 정의됩니다. 이 메소드 는 int.Parse리턴 된 문자열을 수신하여 reader.ReadLine()구문 분석합니다. 물론 비슷한 ReadString방법을 만들 수 있습니다 . 이것으로 충분합니까?
Hosam Aly

잘 넣어 나에게 스트림은 프로그래밍 전체에서 가장 간단하고 강력한 일반적인 추상화입니다. .net basic을 Stream.Copy사용하면 많은 응용 프로그램에서 훨씬 쉽게 생활 할 수 있습니다.
Felype

38

요점은 당신이 백업 저장소가 무엇인지 알 필요가 없다는 것입니다. 그것은 그것의 추상화입니다. 실제로, 백업 저장소 가 없을 수도 있습니다 . 네트워크에서 읽을 수 있으며 데이터가 전혀 "저장되지"않습니다.

파일 시스템, 메모리, 네트워크 또는 스트림 아이디어를 지원하는 다른 것들과 통신하는 코드를 작성할 수 있다면 코드가 훨씬 유연합니다.

또한 스트림은 종종 서로 연결되어 있습니다. 스트림에 넣은 모든 것을 압축하거나 다른 스트림에 압축 된 양식을 쓰거나 데이터를 암호화하는 스트림 등을 가질 수 있습니다. 다른쪽에는 반대가 있습니다 체인, 암호 해독, 압축 해제 등


위의 @HosamAly 예제에 사용 된 다양한 유형의 스트림 리더가 백업 저장소가 무엇인지 아는 것을 의미하지 않습니까? FileStream, NetworkStream 등이 그러한 유형의 소스에서 읽고 있습니다. 또한 백업 저장소가 무엇인지 모르고 프로그램이 실행되는 동안 동적으로 선택되는 경우가 있습니까? 나는 개인적 으로이 문제를 겪지 않았으며 더 많은 것을 알고 싶습니다.
user137717

또한 데이터가 생성 될 때 일부 프로세스를 통해 파이프 데이터를 스트리밍 할 수 있습니까? 아니면 프로세스를 시작할 때 작동하려는 전체 데이터 세트에 액세스해야합니까?
user137717

@ user137717 : 아니요, 단지 StreamReader-또는 더 나은 것을 취하면 TextReader코드는 데이터 흐름의 밑줄 이 어떤 스트림인지 알지 못합니다. 또는 BaseStream속성을 사용하여 유형을 찾을 수 있지만 코드는 이전에 본 적이없는 유형일 수 있습니다. 요점은 당신이 걱정해서는 안된다는 것입니다. 그리고 네, 당신은 할 수 있습니다 절대적으로 때때로 네트워크 스트림에 사용되며 때로는 파일 스트림에 사용되는 코드를 작성 끝낸다. 프로세스 내부 에서 수행되지 않는 프로세스를 통해 데이터를 파이핑 하는 스트림은 스트림 공급자가 될 것입니다.
존 스키트

30

스트림의 요점은 귀하와 백업 저장소 사이에 추상화 계층을 제공하는 것입니다. 따라서 스트림을 사용하는 주어진 코드 블록은 백업 저장소가 디스크 파일, 메모리 등인지 걱정할 필요가 없습니다.


예, 코드를 손상시키지 않고 스트림 유형을 교환 할 수 있습니다. 예를 들어, 한 번의 호출로 파일을 읽은 후 다음 번에 메모리 버퍼를 읽을 수 있습니다.
Craig

파일을 읽거나 쓸 때 파일 탐색 기능이 필요하지 않기 때문에 동일한 코드를 사용하여 쉽게 읽거나 쓸 수있는 스트림을 사용하는 경우가 종종 있습니다. 예를 들어 네트워크 소켓.
alxp

11

개울에 관한 것이 아니라 수영에 관한 것입니다. 하나의 스트림을 수영 할 수 있다면 발생하는 모든 스트림을 수영 할 수있는 것보다 낫습니다.


7

에코 챔버에 추가하기 위해 스트림은 추상화이므로 기본 저장소에 신경 쓰지 않습니다. 스트림이 있거나없는 시나리오를 고려할 때 가장 적합합니다.

스트림은 내가 익숙하지 않은 비 스트림 기반 방법보다 훨씬 많이 수행하지 않기 때문에 대부분 관심이 없습니다. 인터넷 파일부터 시작하겠습니다.

인터넷에서 파일을 다운로드하려면 TCP 소켓을 열고 연결하고 더 이상 바이트가 없을 때까지 바이트를 받아야합니다. 버퍼를 관리하고 예상 파일의 크기를 알고 연결이 끊어진 시점을 감지하고이를 적절하게 처리하는 코드를 작성해야합니다.

일종의 TcpDataStream 객체가 있다고 가정 해 봅시다. 적절한 연결 정보로 작성하고 더 이상 바이트가 없을 때까지 스트림에서 바이트를 읽습니다. 스트림은 버퍼 관리, 데이터 끝 조건 및 연결 관리를 처리합니다.

이러한 방식으로 스트림을 통해 I / O가 더 쉬워집니다. 스트림이 수행하는 작업을 수행하는 TcpFileDownloader 클래스를 작성할 수 있지만 TCP와 관련된 클래스가 있습니다. 대부분의 스트림 인터페이스는 단순히 Read () 및 Write () 메서드를 제공하며 더 복잡한 개념은 내부 구현에 의해 처리됩니다. 이 때문에 동일한 기본 코드를 사용하여 메모리, 디스크 파일, 소켓 및 기타 여러 데이터 저장소를 읽거나 쓸 수 있습니다.


5

내가 사용하는 시각화는 실제 공장이 아니라 컨베이어 벨트입니다. 왜냐하면 그것에 대해 아무것도 모르기 때문에 항목이 선을 따라 움직여서 멍청한 장치로 스탬프 처리되고 상자로 채워지고 계산되고 확인되는 만화 공장에서 사용됩니다.

케이크에 체리를 넣는 장치와 같은 간단한 구성 요소가 있습니다. 이 장치에는 체리리스 케이크의 입력 스트림과 체리가있는 케이크의 출력 스트림이 있습니다. 이러한 방식으로 처리 구조를 언급 할 가치가있는 세 가지 장점이 있습니다.

먼저 구성 요소 자체를 단순화합니다. 케이크에 초콜릿 아이싱을 넣고 싶다면 케이크에 관한 모든 것을 알고있는 복잡한 장치가 필요하지 않습니다. 초콜릿 아이싱을 공급하는 모든 것에 초콜릿 아이싱을 붙이는 바보 같은 장치를 만들 수 있습니다. 만화는 다음 항목이 케이크가 아니라는 것을 알지 못하는 한 Wile E. Coyote입니다).

둘째, 장치를 다른 순서로 배치하여 다른 제품을 만들 수 있습니다. 어쩌면 케이크 위에 장식 대신 체리 대신 체리 위에 장식을하고 싶을 수도 있습니다. 단순히 장치를 회선에서 교체하여 그렇게 할 수 있습니다 .

셋째, 장치는 재고 관리, 권투 또는 개봉을 관리 할 필요가 없습니다. 물건을 모으고 포장하는 가장 효율적인 방법은 변경 가능합니다. 오늘은 오늘 케이크를 48 상자에 넣고 트럭로드로 보내지 만 내일은 맞춤 주문에 따라 6 상자를 보내려고합니다. 이러한 종류의 변경은 생산 라인의 시작과 끝에서 기계를 교체하거나 재구성함으로써 수용 될 수 있습니다. 한 줄에 다른 수의 항목을 처리하기 위해 라인 중간의 체리 기계를 변경할 필요가 없으며 항상 한 번에 하나의 항목으로 작동하며 입력 또는 출력이 어떻게되는지 알 필요가 없습니다. 그룹화되고 있습니다.


설명과 같은 유추의 훌륭한 예.
Richie Thomas

5

처음으로 스트리밍에 대해 들었을 때 웹캠 으로 실시간 스트리밍 하는 상황이었습니다 . 따라서 한 호스트는 비디오 컨텐츠를 브로드 캐스트하고 다른 호스트는 비디오 컨텐츠를 수신합니다. 이 스트리밍입니까? 음 ... 그렇습니다. 그러나 라이브 스트림은 구체적인 개념이며 질문은 스트리밍의 추상적 인 개념을 의미한다고 생각합니다. 참조 https://en.wikipedia.org/wiki/Live_streaming를

그럼 계속 갑시다.


스트리밍 할 수있는 유일한 리소스는 비디오가 아닙니다. 오디오도 스트리밍 할 수 있습니다. 이제 스트리밍 미디어에 대해 이야기하고 있습니다. https://en.wikipedia.org/wiki/Streaming_media를 참조 하십시오 . 오디오는 여러 가지 방법으로 소스에서 대상으로 전달 될 수 있습니다. 몇 가지 데이터 전달 방법을 서로 비교해 봅시다.

클래식 파일 다운로드 클래식 파일 다운로드는 실시간으로 발생하지 않습니다. 파일을 사용하기 전에 다운로드가 완료 될 때까지 기다려야합니다.

프로그레시브 다운로드 프로그레시브 다운로드 청크는 스트리밍 미디어 파일에서 임시 버퍼로 데이터를 다운로드합니다. 해당 버퍼의 데이터를 실행할 수 있습니다. 버퍼의 오디오-비디오 데이터를 재생할 수 있습니다. 그로 인해 사용자는 다운로드하는 동안 스트리밍 미디어 파일을보고들을 수 있습니다. 버퍼를 사용하지 않고 빨리 감기 및 되감기가 가능합니다. 어쨌든 점진적 다운로드는 라이브 스트리밍이 아닙니다.

스트리밍 실시간으로 데이터를 청크합니다. 스트리밍은 생방송으로 구현됩니다. 브로드 캐스트를 듣고있는 클라이언트는 빨리 감기 나 되감기를 할 수 없습니다. 비디오 스트림에서 재생 후 데이터가 삭제됩니다.

스트리밍 서버는 클라이언트와 양방향 연결을 유지하는 반면 웹 서버는 서버 응답 후 연결을 닫습니다.


오디오 및 비디오 만 스트리밍 할 수있는 것은 아닙니다. PHP 매뉴얼에서 스트림의 개념을 살펴 보자.

스트림은 스트리밍 가능한 동작을 나타내는 자원 객체입니다. 즉, 선형 방식 으로 거나 수 있으며 스트림 내의 임의의 위치로 fseek () 할 수 있습니다. 링크 : https://www.php.net/manual/en/intro.stream.php

PHP에서 리소스는 파일, 데이터베이스 연결과 같은 외부 소스에 대한 참조입니다. 다시 말해 스트림은 읽거나 쓸 수있는 소스입니다. 따라서와 함께 fopen()작업했다면 이미 스트림으로 작업 한 것입니다.

스트리밍되는 텍스트 파일의 예 :

// Let's say that cheese.txt is a file that contains this content: 
// I like cheese, a lot! My favorite cheese brand is Leerdammer.
$fp = fopen('cheese.txt', 'r');

$str8 = fread($fp, 8); // read first 8 characters from stream. 

fseek($fp, 21); // set position indicator from stream at the 21th position (0 = first position)
$str30 = fread($fp, 30); // read 30 characters from stream

echo $str8; // Output: I like c 
echo $str30; // Output: My favorite cheese brand is L

Zip 파일도 스트리밍 할 수 있습니다. 또한 스트리밍은 파일로 제한되지 않습니다. HTTP, FTP, SSH 연결 및 입력 / 출력도 스트리밍 할 수 있습니다.


Wikipedia는 스트리밍 개념에 대해 무엇을 말합니까?

컴퓨터 과학에서 스트림은 시간이 지남에 따라 사용 가능한 일련의 데이터 요소입니다. 스트림은 큰 배치가 아닌 한 번에 하나씩 처리되는 컨베이어 벨트의 항목으로 생각할 수 있습니다.

https://en.wikipedia.org/wiki/Stream_%28computing%29를 참조 하십시오 .

Wikipedia는 https://srfi.schemers.org/srfi-41/srfi-41.html에 링크 하고 작가는 스트림에 대해 다음과 같이 말합니다.

지연 목록이라고도하는 스트림은 요청시에만 계산 된 요소를 포함하는 순차적 데이터 구조입니다. 스트림이 널이거나 cdr에서 스트림과 쌍입니다. 스트림의 요소는 액세스 할 때만 계산되므로 스트림은 무한 할 수 있습니다.

따라서 스트림은 실제로 데이터 구조입니다.


결론 : 스트림은 순차적으로 읽거나 쓸 수있는 데이터를 포함 할 수있는 소스입니다. 스트림은 소스에 포함 된 모든 내용을 한 번에 읽지 않고 순차적으로 읽거나 씁니다.


유용한 링크 :

  1. http://www.slideshare.net/auroraeosrose/writing-and-using-php-streams-and-sockets-zendcon-2011 매우 명확한 프리젠 테이션 제공
  2. https://www.sk89q.com/2010/04/introduction-to-php-streams/
  3. http://www.netlingo.com/word/stream-or-streaming.php
  4. http://www.brainbell.com/tutorials/php/Using_PHP_Streams.htm
  5. http://www.sitepoint.com/php-streaming-output-buffering-explained/
  6. http://php.net/manual/en/wrappers.php
  7. http://www.digidata-lb.com/streaming/Streaming_Proposal.pdf
  8. http://www.webopedia.com/TERM/S/streaming.html
  9. https://en.wikipedia.org/wiki/Stream_%28computing%29
  10. https://srfi.schemers.org/srfi-41/srfi-41.html

4

그것은 당신의 인생을 더 편하게 만드는 또 다른 추상화 수준의 개념 일뿐입니다. 그리고 그들은 모두 공통 인터페이스를 가지고있어 파이프와 같은 방식으로 결합 할 수 있습니다. 예를 들어 base64로 인코딩 한 다음 압축하여 디스크에 모두 한 줄로 작성하십시오!


그것은 확실히 유용하지만, 그것이 "완전한 포인트"라고 말하지는 않을 것입니다. 체인을 연결하지 않아도 공통된 추상화를 갖는 것이 유용합니다.
Jon Skeet

그래, 당신 말이 맞아. 나는 이것을 명확히하기 위해 단어를 변경했습니다.
vava

그렇습니다. 내가 너무 까다 롭다고 생각하지 않았기를 바랍니다!
Jon Skeet

3

내가 본 스트림에 대한 가장 좋은 설명 은 SICP의 3 장입니다 . (당신이 이해하기 위해 처음 두 장을 읽어야 할 수도 있지만 어쨌든해야합니다. :-)

바이트에는 steram을 사용하지 않고 정수를 사용합니다. 내가 얻은 큰 점은 다음과 같습니다.

  • 스트림은 지연된 목록입니다
  • [어떤 경우에는 미리 모든 것을 열심히 계산하는] 계산 오버 헤드가 터무니없는
  • 스트림을 사용하여 무한히 긴 시퀀스를 나타낼 수 있습니다

저는 현재 SICP 1 장에 있습니다. 감사!
Rob Sobers

2
하나는 다른 사람들 에게 SICP 스트림 을 말하고 싶습니다 . SICP 스트림 의 중요한 특징 은 게으름 이며, 일반적인 스트림 개념 은 데이터 시퀀스 에 대한 추상화 를 강조합니다 .
象 嘉 道

2

다른 점 (파일 상황을 읽는 경우) :

  1. stream전에 다른 일을 할 수 있습니다 finished reading all content of the file.
  2. 모든 파일 내용을 한 번에로드 할 필요가 없기 때문에 메모리를 절약 할 수 있습니다.

1

스트림을 추상 데이터 소스 (바이트, 문자 등)로 생각하십시오. 네트워크 소켓, 디스크의 파일 또는 웹 서버의 응답 등 구체적인 데이터 소스에서 읽고 쓰는 실제 메커니즘을 추상화합니다.


1

백업 스토어 자체는 종종 또 다른 추상화라고 생각해야합니다. 메모리 스트림은 이해하기 쉽지만 사용중인 파일 시스템에 따라 파일이 크게 다르므로 사용중인 하드 드라이브는 신경 쓰지 마십시오. 모든 스트림이 실제로 백업 저장소 위에있는 것은 아닙니다. 네트워크 스트림은 스트림 일뿐입니다.

스트림의 요점은 우리가 중요한 것에 관심을 제한한다는 것입니다. 표준 추상화를 통해 일반적인 작업을 수행 할 수 있습니다. 예를 들어, 오늘 URL에 대한 파일 또는 HTTP 응답을 검색하고 싶지 않다고해서 내일을 원하지 않는다는 의미는 아닙니다.

스트림은 원래 메모리가 스토리지에 비해 작을 때 생각되었습니다. C 파일을 읽는 것만으로도 큰 부하가 될 수 있습니다. 메모리 풋 프린트를 최소화하는 것이 매우 중요했습니다. 따라서로드 할 필요가 거의없는 추상화가 매우 유용했습니다. 오늘날 네트워크 통신을 수행 할 때 유용하게 사용되며 파일을 처리 할 때 그처럼 제한적인 경우는 거의 없습니다. 일반적인 방식으로 버퍼링과 같은 것을 투명하게 추가 할 수있어 더욱 유용합니다.


0

스트림은 일련의 바이트를 추상화 한 것입니다. 아이디어는 바이트의 출처를 알 필요가 없으며 표준화 된 방식으로 바이트를 읽을 수 있다는 것입니다.

예를 들어 스트림을 통해 데이터를 처리하는 경우 데이터가 파일, 네트워크 연결, 문자열, 데이터베이스의 Blob 등에서 오는 경우 코드에 중요하지 않습니다.

백킹 스토어 구현과 관련이 있다는 점을 제외하면 백킹 스토어 자체와 상호 작용하는 데 아무런 문제가 없습니다.


0

스트림은 데이터와 상호 작용하기위한 표준 메서드 및 속성 집합을 제공하는 추상화입니다. 실제 저장 매체에서 추상화하여 해당 매체가 무엇인지 또는 해당 매체의 구현에 전적으로 의존하지 않고도 코드를 작성할 수 있습니다.

좋은 비유는 가방을 고려하는 것입니다. 가방이 가방 역할을 수행하고 물건을 다시 가져올 수있는 한, 가방이 무엇인지 또는 물건을 넣을 때 무엇을하든 상관 없습니다. 스트림은 백의 개념이 백의 서로 다른 인스턴스 (휴지 백, 핸드백, 배낭 등)에 대해 정의하는 것을 저장 매체에 대해 정의합니다 (상호 작용 규칙).


0

짧게하겠습니다. 여기에 단어가 빠져있었습니다.

스트림은 일반적으로 모든 종류의 데이터를 포함하는 버퍼에 저장 되는 입니다.

(이제 큐가 무엇인지 모두 알고 있으므로 더 이상 설명 할 필요가 없습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.