Відповіді:
Потік представляє послідовність об'єктів (зазвичай байтів, але це не обов'язково), до яких можна отримати доступ у послідовному порядку. Типові операції над потоком:
Певний потік може підтримувати зчитування (у цьому випадку це "потік введення"), запис ("вихідний потік") або те й інше. Не всі потоки можна знайти.
Віджимання є досить рідкісним, але ви завжди можете додати його до потоку, загорнувши реальний вхідний потік в інший вхідний потік, який містить внутрішній буфер. Читання надходять з буфера, а якщо ви натискаєте назад, то дані розміщуються в буфері. Якщо в буфері немає нічого, то потік зворотного потоку зчитується з реального потоку. Це простий приклад "адаптера потоку": він сидить на "кінці" вхідного потоку, він є самим вхідним потоком, і він робить щось зайве, що не було в початковому потоці.
Потік є корисною абстракцією, оскільки він може описувати файли (які насправді є масивами, отже, пошук є простим), але також термінальний вхід / вихід (який не є доступним, якщо не буферизований), сокети, послідовні порти тощо. Отже, ви можете написати код, який говорить або "Я хочу отримати якісь дані, і мені байдуже, звідки вони надходять або як вони потрапили сюди", або "Я видам деякі дані, і від мого абонента повністю залежить, що з ним відбувається". Перший приймає параметр вхідного потоку, другий приймає параметр вихідного потоку.
Найкраща аналогія, яку я можу придумати, - це те, що потік - це конвеєрна стрічка, що йде до вас або веде від вас (або іноді і те й інше). Ви знімаєте матеріал з вхідного потоку, ви ставите речі на вихідний потік. Деякі конвеєри, які ви можете вважати, виходять з отвору в стіні - вони не шукають, читання чи написання - це разова угода. Деякі конвеєри розкладені перед вами, і ви можете рухатись, обираючи місцеперебування у потоці, який ви хочете читати / писати - це шукає.
Як каже IRBMe, однак, найкраще думати про потік з точки зору операцій, які він пропонує (які відрізняються від впровадження до реалізації, але мають багато спільного), а не за фізичною аналогією. Потоки - це "речі, які ви можете прочитати чи написати". Коли ви починаєте підключати адаптери потокового потоку, ви можете розглядати їх як коробку з транспортером та конвеєром, що ви підключаєтесь до інших потоків, а потім вікно здійснює певну трансформацію даних (застібаючи їх або змінюючи стрічки ліній UNIX до DOS, або що завгодно). Труби - це ще одне ретельне випробування метафори: саме там ви створюєте пару потоків, так що все, що ви пишете в одне, можна прочитати з іншого. Подумайте червоточини :-)
Потік - це вже метафора, аналогія, тому насправді не потрібно створювати ще одну. Ви можете думати про це в основному як трубу з потоком води в ній, де вода насправді є даними, а труба - потік. Я гадаю, це свого роду двостороння труба, якщо потік двосторонній. В основному це звичайна абстракція, яка розміщується на речах, де є потік або послідовність даних в одному або обох напрямках.
У таких мовах, як C #, VB.Net, C ++, Java тощо, метафора потоку використовується для багатьох речей. Є потоки файлів, в яких ви відкриваєте файл і можете читати з потоку або записувати в нього безперервно; Існують мережеві потоки, де читання з та запис у потік читає та записує на встановлене мережеве з'єднання. Потоки лише для запису зазвичай називаються вихідними потоками, як у цьому прикладі, і аналогічно, потоки, які призначені лише для читання, називаються вхідними потоками, як у цьому прикладі.
Потік може виконувати перетворення або кодування даних (наприклад, SslStream у .Net, з'їдає дані узгодження SSL і приховує їх від вас; TelnetStream може приховати від вас переговори Telnet, але забезпечити доступ до даних; A ZipOutputStream на Java дозволяє записувати у файли в zip-архіві, не турбуючись про внутрішній формат zip-файлу.
Ще одна поширена річ, яку ви можете знайти - це текстові потоки, які дозволяють писати рядки замість байтів, або деякі мови надають бінарні потоки, що дозволяють писати примітивні типи. Загальна річ, яку ви знайдете в текстових потоках, - це кодування символів, про яке слід пам’ятати.
Деякі потоки також підтримують випадковий доступ, як у цьому прикладі. З іншого боку, мережевий потік з очевидних причин не став би.
Операційні системи, схожі на UNIX, також підтримують потокову модель з програмою введення та виведення, як описано тут .
Надані відповіді поки що відмінні. Я лише надаю іншого, щоб підкреслити, що потік не є послідовністю байтів або специфічним для мови програмування, оскільки концепція є універсальною (хоча її реалізація може бути унікальною). Я часто бачу безліч пояснень в Інтернеті щодо SQL або C або Java, які мають сенс, оскільки файловий потік має справу з місцями пам'яті та операціями низького рівня. Але вони часто звертаються до питання про те, як створити потік файлів та оперувати потенційним файлом на їхній мові, а не обговорюють поняття потоку.
Як згадувалося, а stream
- це метафора, абстрагування чогось більш складного. Для того, щоб ваша фантазія працювала, я пропоную деякі інші метафори:
шланг - потік
шланг, насадка та пов'язані з ними механізми, що дозволяють газу потрапляти у ваш бак - це потік
шосе - це потік
ваші вуха та очі - потоки
Сподіваємось, ви помітите в цих прикладах, що метафори потоку існують лише для того, щоб дозволити щось проїхати по ній (або по ньому у випадку автостради), і вони не завжди створюють те, що вони передають. Важлива відмінність. Ми не називаємо свої вуха як послідовність слів. Шланг все ще є шлангом, якщо через нього не тече вода, але ми повинні підключити його до гнізда, щоб він виконував свою роботу правильно. Автомобіль - не єдиний "вид" транспортного засобу, який може проїхати автострадою.
Таким чином, може існувати потік, який не має даних, що проходять через нього, доки він підключений до файлу .
Далі нам потрібно відповісти на кілька запитань. Я буду використовувати файли для опису потоків так ... Що таке файл? І як ми читаємо файл? Я спробую відповісти на це, зберігаючи певний рівень абстракції, щоб уникнути зайвої складності, і буду використовувати концепцію файлу відносно операційної системи Linux через його простоту та доступність.
Файл - це абстракція :)
Або, як я просто можу пояснити, файл - це частина даних структури, що описує файл, і одна частина даних, яка є фактичним вмістом.
Частина структури даних (називається inode в системах UNIX / Linux) ідентифікує важливі відомості про вміст, але не включає сам вміст (або ім'я файлу для цього питання). Однією з відомостей, які вона зберігає, є адреса пам'яті, де починається вміст. Отже, з ім'ям файлу (або жорстким посиланням у Linux), дескриптором файлу (числовим ім'ям, про яке піклується операційна система) та вихідним розташуванням у пам'яті, ми маємо щось назвати файлом.
(вилучення ключа - "файл" визначається операційною системою, оскільки з ним має вирішуватися ОС, зрештою, і так, файли набагато складніші).
Все йде нормально. Але як нам дістати вміст файлу, сказати любовному листу вашому красуню, щоб ми могли його надрукувати?
Якщо ми починаємо з результату і рухаємось назад, коли ми відкриваємо файл на своєму комп’ютері, весь його вміст вибивається на наш екран, щоб ми читали. Але як? Дуже методично є відповідь. Зміст самого файлу - це ще одна структура даних. Припустимо, масив символів. Ми також можемо думати про це як про струну.
Тож як ми «читаємо» цей рядок? Знаходячи його місце в пам'яті та повторюючи наш масив символів, по одному символу за часом до досягнення кінця символу файлу. Іншими словами програма.
Потік "створюється", коли викликається його програма і має місце пам'яті, до якого можна приєднатися або підключитися . Як і в нашому прикладі шланга для води, шланг неефективний, якщо він не підключений до гнізда. У випадку потоку він повинен бути підключений до файлу, щоб він існував.
Потоки можуть бути вдосконалені, наприклад, потік для отримання вводу або потік для надсилання вмісту файлів на стандартний вихід. UNIX / linux з’єднує та залишає відкритими 3 потоки файлів для нас відразу від bat, stdin (стандартний вхід), stdout (стандартний вихід) та stderr (стандартна помилка). Потоки можуть бути побудовані як самі структури даних або об'єкти, що дозволяє нам виконувати більш складні операції над потоком даних через них, як відкриття потоку, закриття потоку або помилка перевірки файлу, до якого підключений потік. C ++ cin
- приклад об'єкта потоку.
Звичайно, якщо ви вирішите, ви можете написати власний потік.
Потік - це багаторазовий фрагмент коду, який обмежує складність роботи з даними, надаючи корисні операції для виконання даних.
Інша аналогія: Ви не можете плавати проти потоку, тому просто можете взяти наступний біт, байт, рядок або об'єкт із потоку, тоді як вже прочитані дані видаляються. Квиток в одну сторону ... або в основному просто черга, не зберігаючи наполегливості.
То чи потрібні нам черги? Тобі вирішувати.
Слово "потік" було обрано тому, що воно представляє (в реальному житті) дуже схоже значення з тим, що ми хочемо передати, коли ми його використовуємо.
Почніть думати про аналогію з водним потоком. Ви отримуєте безперервний потік даних так само, як вода безперервно тече в річці. Ви не обов'язково знаєте, звідки беруться дані, і найчастіше вам це не потрібно; будь то з файлу, сокета або будь-якого іншого джерела, це насправді не має значення. Це дуже схоже на отримання потоку води, завдяки чому вам не потрібно знати, звідки вона надходить; будь то з озера, фонтану чи будь-якого іншого джерела, це насправді не має значення. джерело