Що таке потік?


Відповіді:


161

Потік представляє послідовність об'єктів (зазвичай байтів, але це не обов'язково), до яких можна отримати доступ у послідовному порядку. Типові операції над потоком:

  • прочитати один байт. Наступного разу, коли ви прочитаєте, ви отримаєте наступний байт тощо.
  • читати кілька байт з потоку в масив
  • шукати (перемістіть поточну позицію в потоці, щоб наступного разу, коли ви прочитали, отримаєте байти з нової позиції)
  • написати один байт
  • записати кілька байтів з масиву в потік
  • пропустити байти з потоку (це як прочитане, але ви ігноруєте дані. Або, якщо вам зручніше, це як шукати, але можна йти лише вперед.)
  • відштовхуйте байти у вхідний потік (це як "скасувати" для читання - ви засуньте кілька байтів назад у потік, щоб наступного разу прочитати саме те, що побачите. Іноді це корисно для парсерів, як це:
  • заглянути (перегляньте байти, не читаючи їх, щоб вони все ще були в потоці, щоб прочитати їх згодом)

Певний потік може підтримувати зчитування (у цьому випадку це "потік введення"), запис ("вихідний потік") або те й інше. Не всі потоки можна знайти.

Віджимання є досить рідкісним, але ви завжди можете додати його до потоку, загорнувши реальний вхідний потік в інший вхідний потік, який містить внутрішній буфер. Читання надходять з буфера, а якщо ви натискаєте назад, то дані розміщуються в буфері. Якщо в буфері немає нічого, то потік зворотного потоку зчитується з реального потоку. Це простий приклад "адаптера потоку": він сидить на "кінці" вхідного потоку, він є самим вхідним потоком, і він робить щось зайве, що не було в початковому потоці.

Потік є корисною абстракцією, оскільки він може описувати файли (які насправді є масивами, отже, пошук є простим), але також термінальний вхід / вихід (який не є доступним, якщо не буферизований), сокети, послідовні порти тощо. Отже, ви можете написати код, який говорить або "Я хочу отримати якісь дані, і мені байдуже, звідки вони надходять або як вони потрапили сюди", або "Я видам деякі дані, і від мого абонента повністю залежить, що з ним відбувається". Перший приймає параметр вхідного потоку, другий приймає параметр вихідного потоку.

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

Як каже IRBMe, однак, найкраще думати про потік з точки зору операцій, які він пропонує (які відрізняються від впровадження до реалізації, але мають багато спільного), а не за фізичною аналогією. Потоки - це "речі, які ви можете прочитати чи написати". Коли ви починаєте підключати адаптери потокового потоку, ви можете розглядати їх як коробку з транспортером та конвеєром, що ви підключаєтесь до інших потоків, а потім вікно здійснює певну трансформацію даних (застібаючи їх або змінюючи стрічки ліній UNIX до DOS, або що завгодно). Труби - це ще одне ретельне випробування метафори: саме там ви створюєте пару потоків, так що все, що ви пишете в одне, можна прочитати з іншого. Подумайте червоточини :-)


3
На сьогодні найкраще пояснення, яке я прочитав. У поєднанні з тим, що написано в SICP ("Обробка потоків дозволяє нам моделювати системи, які мають стан, не використовуючи ніколи даних про призначення, ні змінні дані"), думаю, я нарешті це зрозумів. Дякую!
Кайл Чадха

86

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

У таких мовах, як C #, VB.Net, C ++, Java тощо, метафора потоку використовується для багатьох речей. Є потоки файлів, в яких ви відкриваєте файл і можете читати з потоку або записувати в нього безперервно; Існують мережеві потоки, де читання з та запис у потік читає та записує на встановлене мережеве з'єднання. Потоки лише для запису зазвичай називаються вихідними потоками, як у цьому прикладі, і аналогічно, потоки, які призначені лише для читання, називаються вхідними потоками, як у цьому прикладі.

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

Ще одна поширена річ, яку ви можете знайти - це текстові потоки, які дозволяють писати рядки замість байтів, або деякі мови надають бінарні потоки, що дозволяють писати примітивні типи. Загальна річ, яку ви знайдете в текстових потоках, - це кодування символів, про яке слід пам’ятати.

Деякі потоки також підтримують випадковий доступ, як у цьому прикладі. З іншого боку, мережевий потік з очевидних причин не став би.

  • MSDN дає хороший огляд потоків у .Net.
  • ВС також огляд їх загального OutputStream класу і InputStream класу.
  • У C ++ тут ​​знаходиться документація на istream (вхідний потік), ostream (вихідний потік) та iostream (двонаправлений потік).

Операційні системи, схожі на UNIX, також підтримують потокову модель з програмою введення та виведення, як описано тут .


13

Надані відповіді поки що відмінні. Я лише надаю іншого, щоб підкреслити, що потік не є послідовністю байтів або специфічним для мови програмування, оскільки концепція є універсальною (хоча її реалізація може бути унікальною). Я часто бачу безліч пояснень в Інтернеті щодо SQL або C або Java, які мають сенс, оскільки файловий потік має справу з місцями пам'яті та операціями низького рівня. Але вони часто звертаються до питання про те, як створити потік файлів та оперувати потенційним файлом на їхній мові, а не обговорюють поняття потоку.

Метафора

Як згадувалося, а stream- це метафора, абстрагування чогось більш складного. Для того, щоб ваша фантазія працювала, я пропоную деякі інші метафори:

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

шланг - потік

  1. аналогічно, якби ви хотіли заправити автомобіль газом, ви б пішли на бензонасос, вставили форсунку в ваш бензобак і відкрили клапан, натиснувши важіль блокування.

шланг, насадка та пов'язані з ними механізми, що дозволяють газу потрапляти у ваш бак - це потік

  1. якщо вам потрібно приступити до роботи, ви б почали їздити з дому в офіс, користуючись автострадою.

шосе - це потік

  1. якщо ви хочете вести розмову з кимось, ви б використовували вуха, щоб чути, а рот говорити.

ваші вуха та очі - потоки

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

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

Видалення абстракції

Далі нам потрібно відповісти на кілька запитань. Я буду використовувати файли для опису потоків так ... Що таке файл? І як ми читаємо файл? Я спробую відповісти на це, зберігаючи певний рівень абстракції, щоб уникнути зайвої складності, і буду використовувати концепцію файлу відносно операційної системи Linux через його простоту та доступність.

Що таке файл?

Файл - це абстракція :)

Або, як я просто можу пояснити, файл - це частина даних структури, що описує файл, і одна частина даних, яка є фактичним вмістом.

Частина структури даних (називається inode в системах UNIX / Linux) ідентифікує важливі відомості про вміст, але не включає сам вміст (або ім'я файлу для цього питання). Однією з відомостей, які вона зберігає, є адреса пам'яті, де починається вміст. Отже, з ім'ям файлу (або жорстким посиланням у Linux), дескриптором файлу (числовим ім'ям, про яке піклується операційна система) та вихідним розташуванням у пам'яті, ми маємо щось назвати файлом.

(вилучення ключа - "файл" визначається операційною системою, оскільки з ним має вирішуватися ОС, зрештою, і так, файли набагато складніші).

Все йде нормально. Але як нам дістати вміст файлу, сказати любовному листу вашому красуню, щоб ми могли його надрукувати?

Читання файлу

Якщо ми починаємо з результату і рухаємось назад, коли ми відкриваємо файл на своєму комп’ютері, весь його вміст вибивається на наш екран, щоб ми читали. Але як? Дуже методично є відповідь. Зміст самого файлу - це ще одна структура даних. Припустимо, масив символів. Ми також можемо думати про це як про струну.

Тож як ми «читаємо» цей рядок? Знаходячи його місце в пам'яті та повторюючи наш масив символів, по одному символу за часом до досягнення кінця символу файлу. Іншими словами програма.

Потік "створюється", коли викликається його програма і має місце пам'яті, до якого можна приєднатися або підключитися . Як і в нашому прикладі шланга для води, шланг неефективний, якщо він не підключений до гнізда. У випадку потоку він повинен бути підключений до файлу, щоб він існував.

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

Звичайно, якщо ви вирішите, ви можете написати власний потік.

Визначення

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


Отже, потік - це середовище, через яке протікають дані. Він повинен бути підключений до джерела даних, і він може виконувати операції над собою та з даними, що протікають через нього.
КінгБріан

так. моя єдина причина писати додаткову відповідь - пояснити, що потік може існувати, навіть якщо дані не протікають через нього. тоді як IRL потоку (з водою та ін.) перестає бути потоком, коли вода перестає текти і може спричинити плутанину при роздумах про аналогію.
rekurzion

1
Зараз я вивчаю Java, і ваша відповідь допомогла мені обернути голову навколо неї.
КінгБріан

6

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


6

Інша аналогія: Ви не можете плавати проти потоку, тому просто можете взяти наступний біт, байт, рядок або об'єкт із потоку, тоді як вже прочитані дані видаляються. Квиток в одну сторону ... або в основному просто черга, не зберігаючи наполегливості.

То чи потрібні нам черги? Тобі вирішувати.


це означає, що у потоці вам потрібно йти вперед, не може рухатися назад. Крім того, попередні дані видаляються як ви йдете вперед, які зберігають пам'ять? Правильно
Мухаммед Файзан Хан

5

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

Почніть думати про аналогію з водним потоком. Ви отримуєте безперервний потік даних так само, як вода безперервно тече в річці. Ви не обов'язково знаєте, звідки беруться дані, і найчастіше вам це не потрібно; будь то з файлу, сокета або будь-якого іншого джерела, це насправді не має значення. Це дуже схоже на отримання потоку води, завдяки чому вам не потрібно знати, звідки вона надходить; будь то з озера, фонтану чи будь-якого іншого джерела, це насправді не має значення. джерело

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.