문제

프로그래밍 세계의 스트림은 무엇입니까? 왜 우리는 그것을 필요로합니까?

가능하면 비유의 도움으로 친절하게 설명하십시오.

도움이 되었습니까?

해결책

스트림은 순차적으로 액세스 할 수있는 일련의 객체 (일반적으로 바이트이지만 반드시 그렇지는 않음)를 나타냅니다. 스트림에서의 일반적인 작업 :

  • 하나의 바이트를 읽으십시오. 다음에 읽을 때 다음 바이트 등을 얻을 수 있습니다.
  • 스트림에서 배열로 여러 바이트를 읽습니다
  • SEEK (스트림에서 현재 위치를 이동하여 다음에 읽을 때 새 위치에서 바이트를 얻습니다).
  • 하나의 바이트를 작성하십시오
  • 배열에서 스트림에 여러 바이트를 작성하십시오
  • 스트림에서 바이트를 건너 뛰십시오 (이것은 읽기와 같지만 데이터를 무시합니다. 또는 선호하는 경우 Seek와 같지만 앞으로 나아갈 수 있습니다.)
  • 바이트를 입력 스트림으로 뒤로 밀어 넣으십시오 (이것은 읽기를위한 "실행 취소"와 같습니다. 스트림을 백업하는 바이트를 뒤로 밀어서 다음에 읽을 때 볼 수 있습니다. 때때로 파서에 유용합니다.
  • 엿보기 (읽지 않고 바이트를 보면 나중에 읽을 수 있도록 여전히 스트림에 있습니다).

특정 스트림은 읽기 (이 경우 "입력 스트림"), 쓰기 ( "출력 스트림") 또는 둘 다를 지원할 수 있습니다. 모든 스트림이 찾을 수있는 것은 아닙니다.

푸시 백은 상당히 드물지만 내부 버퍼를 보유하는 다른 입력 스트림에 실제 입력 스트림을 감싸서 항상 스트림에 추가 할 수 있습니다. 읽기는 버퍼에서 나오고 뒤로 밀면 데이터가 버퍼에 배치됩니다. 버퍼에 아무것도 없으면 푸시 백 스트림은 실제 스트림에서 읽습니다. 이것은 "스트림 어댑터"의 간단한 예입니다. 입력 스트림의 "끝"에 있으며 입력 스트림 자체이며 원래 스트림이하지 않은 추가 기능을 수행합니다.

스트림은 파일 (실제로 배열이므로 찾는 것이 간단합니다)이지만 터미널 입력/출력 (버퍼링되지 않으면 찾을 수 없음), 소켓, 직렬 포트 등을 설명 할 수 있기 때문에 유용한 추상화입니다. 따라서 코드를 작성할 수 있습니다. "나는 일부 데이터를 원하고 어디에서 왔는지 또는 어떻게 여기에 왔는지 신경 쓰지 않습니다"또는 "일부 데이터를 생성 할 것입니다. 전자는 입력 스트림 매개 변수를 가져오고 후자는 출력 스트림 매개 변수를 취합니다.

내가 생각할 수있는 가장 좋은 비유는 스트림이 당신을 향해 오거나 당신에게서 멀어 지도록 컨베이어 벨트라는 것입니다. 입력 스트림에서 물건을 벗고 출력 스트림에 물건을 넣습니다. 벽의 구멍에서 나오는 것으로 생각할 수있는 일부 컨베이어는 찾을 수 없거나 읽거나 쓰는 것이 일회성 거래입니다. 일부 컨베이어는 당신 앞에 배치되어 있으며, 당신은 당신이 읽고 싶은 스트림에서 어디에서 선택을 선택할 수 있습니다 - 그것은 찾고 있습니다.

그러나 Irbme이 말했듯이, 물리적 비유보다는 제공하는 운영 (구현마다 다르지만 공통적 인 공통점이 많음) 측면에서 스트림을 생각하는 것이 가장 좋습니다. 스트림은 "읽거나 쓸 수있는 것"입니다. 스트림 어댑터를 연결하기 시작하면 컨베이어를 넣은 상자로 생각하고 컨베이어가 다른 스트림에 연결 한 다음 상자가 데이터에 약간의 변환을 수행한다고 생각할 수 있습니다 (Zipping 또는 Unix LineFeeds 변경 dos 또는 무엇이든). 파이프는 은유에 대한 또 다른 철저한 테스트입니다. 그곳에서 당신은 당신이 한 쌍의 스트림을 만들어 당신이 하나에 쓰는 것이 다른 하나에서 읽을 수 있습니다. 웜홀을 생각하십시오 :-)

다른 팁

스트림은 이미 은유, 비유이므로 다른 것을 담배 할 필요가 없습니다. 당신은 기본적으로 물이 실제로 데이터이고 파이프가 스트림 인 물의 흐름이있는 파이프로 생각할 수 있습니다. 스트림이 양방향이면 일종의 2 방향 파이프라고 생각합니다. 기본적으로 하나 또는 양쪽 방향으로 일련의 데이터가있는 것들에 대한 공통 추상화입니다.

C#, vb.net, C ++, Java 등과 같은 언어에서 스트림 은유는 많은 것들에 사용됩니다. 파일 스트림이 있으며 파일을 열고 스트림에서 읽거나 지속적으로 쓸 수 있습니다. 스트림에 대한 읽기 및 쓰기가 기본 확립 된 네트워크 연결을 읽고 쓰는 네트워크 스트림이 있습니다. 글쓰기만을위한 스트림은 일반적으로 출력 스트림으로 호출됩니다. 이것 예를 들어, 마찬가지로, 읽기만을위한 스트림은 입력 스트림으로 호출됩니다. 이것 예시.

스트림은 데이터의 변환 또는 인코딩을 수행 할 수 있습니다 ( sslstream 예를 들어 .NET에서 SSL 협상 데이터를 먹고 숨길 것입니다. TelnetStream은 Telnet 협상을 숨길 수 있지만 데이터에 대한 액세스를 제공 할 수 있습니다. ㅏ zipoutputStream Java에서는 Zip 파일 형식의 내부에 대해 걱정할 필요없이 Zip 아카이브로 파일에 쓸 수 있습니다.

당신이 찾을 수있는 또 다른 일반적인 것은 바이트 대신 문자열을 쓸 수있는 텍스트 스트림 또는 일부 언어는 원시 유형을 쓸 수있는 이진 스트림을 제공합니다. 텍스트 스트림에서 찾을 수있는 일반적인 것은 문자 인코딩입니다.

일부 스트림은 또한 임의의 액세스를 지원합니다 이것 예시. 반면에 네트워크 스트림은 명백한 이유로 그렇지 않을 것입니다.

  • MSDN .NET에서 스트림에 대한 좋은 개요를 제공합니다.
  • Sun은 또한 장군에 대한 개요를 가지고 있습니다 출력 스트림 수업 및 입력 스트림 수업.
  • C ++에서는 여기에 있습니다 istream (입력 스트림), 타조 (출력 스트림) 및 ioStream (양방향 스트림) 문서.

유사한 운영 체제도 설명대로 프로그램 입력 및 출력으로 스트림 모델도 지원합니다. 여기.

위에서 언급 한 것 외에도 스키마 또는 하스켈과 같은 기능 프로그래밍 언어로 정의 된 다른 스트림이 있습니다.

또 다른 비유 : 스트림에 대해 수영을 할 수 없으므로 크림에서 다음 비트, 바이트, 스트림 또는 객체를 취할 수 있고 이미 읽은 데이터는 삭제됩니다. 일방 통행량 ... 또는 기본적으로 a 대기줄 지속성을 저장하지 않고.

그래서 우리는 줄이 필요합니까? 당신은 결정합니다.

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

물 흐름에 대한 비유에 대해 생각하기 시작하십시오. 물이 강에서 지속적으로 흐르는 것처럼 지속적인 데이터 흐름을받습니다. 데이터가 어디에서 왔는지 반드시 알 필요는 없으며 대부분 필요하지 않습니다. 파일, 소켓 또는 기타 소스에서 나오면 실제로는 중요하지 않습니다. 이것은 물 흐름을받는 것과 매우 유사하며, 어디에서 왔는지 알 필요가 없습니다. 호수, 분수 또는 다른 출처에서 나오면 실제로는 중요하지 않습니다. 원천

지금까지 주어진 답변은 훌륭합니다. 나는 개념이 보편적이기 때문에 스트림이 일련의 바이트 시퀀스이거나 프로그래밍 언어에 특정한 것이 아니라는 것을 강조하기 위해 또 다른 것을 제공하고 있습니다 (구현은 고유 할 수 있음). 나는 종종 SQL 또는 C 또는 Java 측면에서 온라인으로 많은 설명을 볼 수 있으며, 이는 메모리 위치 및 낮은 수준의 운영을 처리하는 것이 좋습니다. 그러나 그들은 종종 스트림의 개념에 대해 논의하기보다는 filestream을 만들고 잠재적 파일에서 주어진 언어로 작동하는 방법을 다룹니다.

은유

언급했듯이 a stream 은유, 더 복잡한 것의 추상화입니다. 당신의 상상력을 발휘하기 위해 나는 다른 은유를 제공합니다.

  1. 빈 수영장을 물로 채우고 싶습니다. 이를 달성하는 한 가지 방법은 호스를 스피터에 부착하여 수영장에 호스의 끝을 놓고 물을 켜는 것입니다.

호스는 스트림입니다

  1. 마찬가지로, 가스로 자동차를 리필하려면 가스 펌프로 가서 노즐을 가스 탱크에 삽입하고 잠금 레버를 압박하여 밸브를 열게됩니다.

가스가 탱크로 흐르도록 허용하는 호스, 노즐 및 관련 메커니즘은 스트림입니다.

  1. 일을 해야하는 경우 고속도로를 사용하여 집에서 사무실로 운전하기 시작합니다.

고속도로는 스트림입니다

  1. 누군가와 대화를 원한다면 귀를 사용하고 입을 말할 것입니다.

귀와 눈은 개울입니다

이 예에서 스트림 은유가 무언가를 여행 할 수 있도록 (또는 고속도로의 경우) 무언가가 존재한다는 것을 알기를 바랍니다. 중요한 차이. 우리는 귀를 일련의 단어라고 부릅니다. 물이 흐르지 않으면 호스는 여전히 호스입니다. 그러나 우리는 그것을 올바르게 작업하기 위해 스피터에 연결해야합니다. 자동차는 고속도로를 가로 지르는 유일한 차량이 아닙니다.

따라서 스트림이 그대로 이동하는 데이터가없는 스트림이 존재할 수 있습니다. 연결 a 파일.

추상화 제거

다음으로 몇 가지 질문에 답해야합니다. 스트림을 설명하기 위해 파일을 사용하겠습니다 ... 파일이란 무엇입니까? 파일을 어떻게 읽습니까? 불필요한 복잡성을 피하기 위해 특정 수준의 추상화를 유지하면서 이에 대답하려고 시도하고 단순성과 접근성 때문에 Linux 운영 체제에 대한 파일의 개념을 사용할 것입니다.

파일이란 무엇입니까?

파일은 추상화입니다 :)

또는 간단히 설명 할 수 있듯이 파일은 파일을 설명하는 하나의 부분 및 실제 콘텐츠 인 일부 부품 데이터입니다.

데이터 구조 부분 (UNIX/Linux 시스템의 inode라고 함)은 컨텐츠에 대한 중요한 정보를 ID이지만 콘텐츠 자체 (또는 해당 파일의 이름)는 포함하지 않습니다. 보관하는 정보 중 하나는 컨텐츠가 시작되는 위치에 대한 메모리 주소입니다. 따라서 파일 이름 (또는 Linux의 하드 링크), 파일 디스크립터 (운영 체제가 관심을 갖는 숫자 파일 이름) 및 메모리의 시작 위치가 파일을 호출 할 수있는 것이 있습니다.

(주요 테이크 아웃은 '파일'은 운영 체제에 의해 정의됩니다. 궁극적으로 그것을 다루어야하는 OS이기 때문입니다. 그렇습니다. 파일 훨씬 더 복잡합니다).

여태까지는 그런대로 잘됐다. 그러나 파일의 내용을 어떻게 얻습니까?

파일 읽기

결과에서 시작하여 뒤로 이동하면 컴퓨터에서 파일을 열면 전체 내용이 화면에 튀어 나와 읽을 수 있습니다. 하지만 어떻게? 매우 체계적으로 대답입니다. 파일 자체의 내용은 또 다른 데이터 구조입니다. 문자 배열을 가정 해보십시오. 우리는 이것을 문자열로 생각할 수도 있습니다.

그렇다면 우리는 어떻게이 문자열을 '읽습니까'? 메모리에서 위치를 찾아서 캐릭터 배열을 통해 반복함으로써 파일 문자가 끝날 때까지 한 번에 한 문자. 다시 말해서 프로그램.

스트림은 프로그램이 호출되고 메모리 위치가있는 경우 '생성'됩니다. 에 연결하다 또는 연결하십시오. 우리의 물 호스 예와 마찬가지로, 호스는 스피터에 연결되지 않으면 효과가 없습니다. 스트림의 경우 파일에 연결되어 있어야합니다.

스트림은 예를 들어 입력을 수신하는 스트림 또는 스트림을 표준 출력으로 전송하는 스트림을 더 세분화 할 수 있습니다. UNIX/Linux는 BAT, Stdin (표준 입력), Stdout (표준 출력) 및 STDERR (표준 오류)을 바로 연결하고 3 개의 파일 스트림을 열고 유지합니다. 스트림은 데이터 구조 자체 또는 객체로 구축 될 수있어 스트림 열기, 스트림 닫기 또는 스트림이 연결된 파일을 확인하는 등의 데이터 스트리밍을 통해 데이터 스트리밍의 복잡한 작업을 수행 할 수 있습니다. C ++ 's cin 스트림 객체의 예입니다.

확실히, 당신이 선택한다면, 당신은 당신의 자신의 스트림을 쓸 수 있습니다.

정의

스트림은 데이터를 처리 할 수있는 유용한 작업을 제공하면서 데이터를 처리하는 복잡성을 추상화하는 재사용 가능한 코드입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top