Что такое поток? - PullRequest
       42

Что такое поток?

103 голосов
/ 01 августа 2009

Что такое поток в мире программирования? Зачем нам это нужно?

Пожалуйста, объясните с помощью аналогии, если это возможно.

Ответы [ 6 ]

131 голосов
/ 01 августа 2009

Поток представляет собой последовательность объектов (обычно байтов, но не обязательно), к которым можно обращаться в последовательном порядке. Типичные операции над потоком:

  • читать один байт. При следующем чтении вы получите следующий байт и т. Д.
  • чтение нескольких байтов из потока в массив
  • seek (переместить текущую позицию в потоке, чтобы при следующем чтении вы получали байты с новой позиции)
  • записать один байт
  • записать несколько байтов из массива в поток
  • пропустить байты из потока (это похоже на чтение, но вы игнорируете данные. Или, если вы предпочитаете, это похоже на поиск, но может идти только вперед.)
  • сдвинуть назад байты во входной поток (это похоже на «отмену» для чтения - вы выталкиваете несколько байтов обратно в поток, так что в следующий раз, когда вы читаете, это то, что вы увидите. Это иногда полезно для анализаторов, так как это:
  • peek (посмотрите на байты, не читая их, чтобы они все еще были в потоке для последующего чтения)

Определенный поток может поддерживать чтение (в этом случае это «входной поток»), запись («выходной поток») или оба. Не все потоки доступны для поиска.

Откат назад довольно редок, но вы всегда можете добавить его в поток, поместив реальный входной поток в другой входной поток, который содержит внутренний буфер. Чтения поступают из буфера, и если вы нажмете назад, данные будут помещены в буфер. Если в буфере ничего нет, то обратный поток считывает из реального потока. Это простой пример «потокового адаптера»: он находится на «конце» входного потока, он сам является входным потоком и делает что-то дополнительное, чего не сделал исходный поток.

Поток - это полезная абстракция, поскольку он может описывать файлы (которые на самом деле являются массивами, следовательно, поиск прост), а также ввод / вывод терминала (который не доступен для поиска, если не буферизован), сокеты, последовательные порты и т. Д. Таким образом, вы можете написать код, который говорит: «Мне нужны какие-то данные, и мне все равно, откуда они или как они сюда попали», или «Я создам некоторые данные, и все, что с ними происходит, полностью зависит от моего вызывающего». Первый принимает параметр входного потока, второй принимает параметр выходного потока.

Лучшая аналогия, которую я могу придумать, - это то, что поток - это конвейер, идущий к вам или уводящий от вас (или иногда оба). Вы убираете вещи из входного потока, вы помещаете вещи в выходной поток. Некоторые конвейеры, о которых вы можете подумать, выходят из дыры в стене - их нельзя найти, чтение или запись - разовая сделка. Некоторые конвейеры выложены перед вами, и вы можете двигаться дальше, выбирая местонахождение в потоке, который вы хотите читать / писать - это поиск.

Однако, как говорит IRBMe, лучше рассматривать поток с точки зрения операций, которые он предлагает (которые варьируются от реализации к реализации, но имеют много общего), а не по физической аналогии. Потоки - это «вещи, которые вы можете читать или писать». Когда вы начинаете подключать потоковые адаптеры, вы можете думать о них как о блоке с входящим и выходным конвейером, который вы подключаете к другим потокам, а затем блок выполняет некоторое преобразование данных (сжатие его или изменение перевода строки UNIX). для DOS или что угодно). Каналы - это еще один тщательный тест метафоры: здесь вы создаете пару потоков, так что все, что вы пишете в один, может быть прочитано из другого. Подумайте, червоточины: -)

53 голосов
/ 01 августа 2009

Поток - это уже метафора, аналогия, так что на самом деле нет необходимости показывать другой. Вы можете думать об этом в основном как о трубе с потоком воды, в которой вода на самом деле является данными, а труба - потоком. Я предполагаю, что это своего рода двусторонняя труба, если поток двунаправленный. По сути, это обычная абстракция, которая помещается в объекты, в которых поток или последовательность данных находятся в одном или обоих направлениях.

В таких языках, как C #, VB.Net, C ++, Java и т. Д., Метафора потока используется для многих вещей. Существуют файловые потоки, в которых вы открываете файл и можете читать из потока или писать в него непрерывно; Существуют сетевые потоки, в которых чтение и запись в поток выполняет чтение и запись в установленное сетевое соединение. Потоки только для записи обычно называются выходными потоками, как в этом примере, и аналогично, потоки, предназначенные только для чтения, называются входными потоками, как в этом примере.

Поток может выполнять преобразование или кодирование данных (например, SslStream в .Net будет поглощать данные согласования SSL и скрывать их от вас; TelnetStream может скрыть переговоры Telnet от вас , но предоставляют доступ к данным; A ZipOutputStream в Java позволяет записывать файлы в zip-архиве, не беспокоясь о внутренностях формата zip-файла.

Другая распространенная вещь, которую вы можете найти, это текстовые потоки, которые позволяют вам писать строки вместо байтов, или некоторые языки предоставляют двоичные потоки, которые позволяют вам писать примитивные типы. В текстовых потоках вы часто встречаетесь с кодировкой символов, о которой вам следует знать.

Некоторые потоки также поддерживают произвольный доступ, как в этом примере. С другой стороны, сетевой поток по понятным причинам не будет.

  • MSDN дает хороший обзор потоков в .Net.
  • Sun также имеет общий обзор OutputStream класса и InputStream класса.
  • В C ++ приведена документация istream (входной поток), ostream (выходной поток) и iostream (двунаправленный поток).

UNIX-подобные операционные системы также поддерживают потоковую модель с программным вводом и выводом, как описано здесь .

6 голосов
/ 01 августа 2009

В дополнение к вышеперечисленным вещам существует другой вид потоков - как определено в функциональных языках программирования, таких как Scheme или Haskell, - возможно, бесконечная структура данных, которая генерируется некоторой функцией по требованию.

5 голосов
/ 14 февраля 2013

Еще одна аналогия: вы не можете плыть против потока, поэтому вы можете просто взять следующий бит, байт, строку или объект из потока, пока уже прочитанные данные будут удалены. Билет в один конец ... или просто очередь без сохранения.

Так нам нужны очереди? Вы решаете.

4 голосов
/ 07 января 2019

Ответы, данные до сих пор, превосходны. Я только предоставляю другой, чтобы подчеркнуть, что поток не является последовательностью байтов или специфичен для языка программирования, поскольку концепция универсальна (хотя ее реализация может быть уникальной). Я часто вижу в Интернете множество объяснений в терминах SQL, C или Java, которые имеют смысл, поскольку файловый поток имеет дело с областями памяти и операциями низкого уровня. Но они часто рассматривают, как создать файловый поток и работать с потенциальным файлом на их данном языке, а не обсуждать концепцию потока.

Метафора

Как уже упоминалось, stream - это метафора, абстракция чего-то более сложного. Чтобы ваше воображение заработало, я предлагаю несколько других метафор:

  1. Вы хотите заполнить пустой бассейн водой. Один из способов сделать это - прикрепить шланг к патрубку, положить конец шланга в бассейн и включить воду.

шланг струйный

  1. Точно так же, если вы хотите заправить свой автомобиль газом, вы должны пойти к газовому насосу, вставить форсунку в бензобак и открыть клапан, нажав на фиксирующий рычаг.

шланг, форсунка и связанные с ними механизмы, позволяющие газу поступать в ваш бак - это поток

  1. если вам нужно добраться до работы, вы поедете из дома в офис по автостраде.

Автострада - это поток

  1. если вы хотите поговорить с кем-то, вы бы использовали слух, чтобы слышать, и рот, чтобы говорить.

ваши уши и глаза - потоки

Надеюсь, вы заметите в этих примерах, что метафоры потока существуют только для того, чтобы что-то проходило через него (или на нем в случае автострады), и не всегда сами представляют собой то, что переносят. Важное различие. Мы не называем наши уши как последовательность слов. Шланг остается шлангом, если через него не течет вода, но мы должны подсоединить его к патрубку, чтобы он правильно выполнял свою работу. Автомобиль - не единственный вид транспорта, способный пересечь автостраду.

Таким образом, может существовать поток, в котором нет данных, проходящих через него, если он подключен к файлу .

Удаление абстракции

Далее нам нужно ответить на несколько вопросов. Я собираюсь использовать файлы для описания потоков, так что ... Что такое файл? И как мы читаем файл? Я попытаюсь ответить на это, поддерживая определенный уровень абстракции, чтобы избежать ненужной сложности, и буду использовать концепцию файла относительно операционной системы Linux из-за ее простоты и доступности.

Что такое файл?

Файл является абстракцией:)

Или, насколько я могу объяснить, файл - это структура данных из одной части, описывающая файл, и данные из одной части, которые являются фактическим содержимым.

Часть структуры данных (называемая inode в системах UNIX / linux) идентифицирует важные фрагменты информации о контенте, но не включает в себя сам контент (или имя файла в этом отношении). Одна из частей информации, которую он хранит, - это адрес памяти, с которого начинается содержимое. Таким образом, с именем файла (или жесткой ссылкой в ​​linux), дескриптором файла (числовое имя файла, о котором заботится операционная система) и начальной точкой в ​​памяти, у нас есть нечто, что мы можем назвать файлом.

(ключевое слово «файл» определяется операционной системой, поскольку именно ОС в конечном итоге должна с этим справляться. И да, файлы намного сложнее).

Пока все хорошо. Но как нам получить содержимое файла, сказать любовное письмо вашему любимому, чтобы мы могли распечатать его?

Чтение файла

Если мы начнем с результата и двинемся назад, когда мы открываем файл на нашем компьютере, все его содержимое попадает на экран, чтобы мы могли его прочитать. Но как? Очень методично это ответ. Содержимое самого файла является другой структурой данных. Предположим, массив символов. Мы также можем думать об этом как о строке.

Так, как мы «читаем» эту строку? Находя его местоположение в памяти и перебирая наш массив символов, по одному символу за раз до достижения конца файла. Другими словами, программа.

Поток «создается», когда вызывается его программа, и он имеет область памяти для подключения к или подключения к . Как и в нашем примере с водяным шлангом, шланг неэффективен, если он не подсоединен к патрубку. В случае потока он должен быть подключен к файлу, чтобы он существовал.

Потоки могут быть дополнительно уточнены, например, поток для приема ввода или поток для отправки содержимого файлов на стандартный вывод. UNIX / linux соединяет и сохраняет открытыми 3 файловых потока для нас сразу, stdin (стандартный ввод), stdout (стандартный вывод) и stderr (стандартная ошибка). Потоки могут быть построены как сами структуры данных или объекты, что позволяет нам выполнять более сложные операции потоковой передачи данных через них, такие как открытие потока, закрытие потока или проверка ошибок файла, к которому подключен поток. C ++ cin является примером объекта потока.

Конечно, если вы захотите, вы можете написать свой собственный поток.

Определение

Поток - это многократно используемый фрагмент кода, который абстрагируется от сложности работы с данными, обеспечивая при этом полезные операции для обработки данных.

4 голосов
/ 25 ноября 2015

Слово «поток» было выбрано, потому что оно представляет (в реальной жизни) значение, очень похожее на то, что мы хотим передать, когда используем его.

Начните думать об аналогии с потоком воды. Вы получаете непрерывный поток данных, точно так же, как вода непрерывно течет в реке. Вы не обязательно знаете, откуда поступают данные, и чаще всего вам это не нужно; будь то из файла, сокета или любого другого источника, это не имеет (не должно) никакого значения. Это очень похоже на получение потока воды, при котором вам не нужно знать, откуда он исходит; будь то озеро, фонтан или любой другой источник, это не имеет (не должно) никакого значения. источник

...