Що саме означає «Потік» та «Буфер» у введенні / виведенні Java?


85

Я щойно дізнався про введення / виведення за допомогою BufferedReader.

Я хотів знати, які саме значення цього терміна Streamі Buffer?

Також для чого нам служить цей рядок коду:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

Відповіді:


202

Java має два типи класів для введення та виведення (I / O): потоки та читачі / записи .

Streams ( InputStream, OutputStreamі все , що розширює їх) призначене для читання і запису двійкових даних з файлів, мереж, або який - або іншого пристрою.

Читачі та письменники призначені для читання та написання тексту (символів). Вони являють собою шар поверх потоків, який перетворює двійкові дані (байти) в символи і назад, використовуючи кодування символів .

Читання даних з дискового байта за байтом дуже неефективне. Одним із способів пришвидшити його є використання буфера: замість того, щоб читати по одному байту, ви читаєте відразу кілька тисяч байтів і поміщаєте їх у буфер в пам’ять. Потім ви можете по черзі переглянути байти в буфері.

Підручник Oracle щодо вводу-виводу в Java детально пояснює це.

Переглядаючи рядок коду, який ви надали:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

System.inє InputStream. Ви створюєте, InputStreamReaderякий читає байти з System.in. Потім ви обертаєте це в BufferedReader.

Отже, зрештою, у вас є таке, BufferedReaderщо читає з того, InputStreamReaderщо читає з System.in.


1
Дякуємо за вашу відповідь, але у мене сплутаність. Як ви сказали, ми читаємо відразу кілька тисяч байтів і поміщаємо їх у буфер; так це означає, що буфер - це просто місце в пам'яті, де ми зберігаємо речі?
користувач122345656

3
@Jesper. Ви сказали: "Один із способів пришвидшити це використання буфера: замість того, щоб читати по одному байту, ви читаєте відразу кілька тисяч байтів і поміщаєте їх у буфер в пам'ять. Потім ви можете подивитися на байти в буфері по одному ". Так, це правда, але я думаю, що з буфером також по одному байту читається за раз. Єдина різниця, я вважаю, що він поміщений в буфер і програма, а потім читає його з буфера замість диска
M Sach

7
@ user122345656 Так, буфер - це місце в пам'яті для тимчасового зберігання даних.
Jesper

14
@MSach Подумайте, що відбувається, коли ви хочете прочитати дані з жорсткого диска. Щоб прочитати байт у певному місці, вам слід почекати, поки диск обернеться, поки головка не опиниться над місцем на диску, де знаходиться байт для читання. Якщо ви прочитали лише 1 байт на той момент, а наступний байт пізніше, вам доведеться почекати, поки диск здійснить повне обертання, щоб прочитати наступний байт. Набагато ефективніше читати блок послідовних байтів.
Jesper

2
Потоки @parsecer призначені для читання байтів; читачі призначені для читання тексту (символів). InputStreamReaderє обгорткою навколо файлу, InputStreamщо дозволяє читати текст із InputStream. Якщо ви просто хочете прочитати байти (не символи), вам це не потрібно InputStreamReader. Це корисно, якщо ви хочете інтерпретувати байти як текстові символи.
Jesper

20

Буфер:

Це область фізичної пам'яті, яка використовується для тимчасового зберігання даних під час їх переміщення з одного місця в інше. Це фізична пам’ять у більшості випадків буде оперативною пам’яттю (оперативною пам’яттю).

Але з контексту цього питання, Buffer використовується під час читання / запису даних. Його не потрібно використовувати під час переміщення даних з одного місця в інше.

Приклад для буфера: Якщо у вашій системі є 4 ГБ оперативної пам'яті, система може виділити для буфера 4 КБ пам’яті (RAM) . КБ - Кілобайт (и), ГБ - Гігабайт (и)

Потік вводу-виводу (або) Потік:

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

Введення / виведення означає вхід / вихід.

Отже, Input Stream може бути джерелом вхідних даних, наприклад, файлом на диску, мережевим підключенням тощо.

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

Згідно з офіційною документацією JAVA , потоки бувають 3-х типів.

  1. Потоки байтів (читання або запис байтів)
  2. Потоки символів (читання або запис символів)
  3. Буферовані потоки ( для ефективності читайте з буфера або пишіть до нього )

Байтові потоки:

Вони виконують введення та виведення 8-бітових байтів. Усі класи байтових потоків походять від InputStream та OutputStream .

Класи потоку введення байтів отримують введення як вихідні байти . Класи потоку вихідних байтів дають вихід як вихідні байти .

InputStream- Прямі відомі підкласи

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream.

OutputStream- Прямі відомі підкласи

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

Потоки символів: Вони є шаром поверх байтових потоків. Вони перетворюють байти (двійкові дані) в символи, а символи в байти, використовуючи кодування символів.

Усі класи потоків символів походять від Reader та Writer .

Reader - Прямі відомі підкласи

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Writer - Прямі відомі підкласи

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Байтові потоки та символьні потоки використовують небуферований ввід / вивід .

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

Буферовані потоки:

Буферизовані вхідні потоки зчитують дані з області пам'яті, відомої як буфер ; власний вхідний API викликається лише тоді, коли буфер порожній.

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

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

Приклад:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

Існує 4 буферизовані класи потоків, які використовуються для обтікання буферизованих потоків:

Для створення буферованих байтових потоків використовуйте BufferedInputStreamта BufferedOutputStreamкласи.

Для створення буферизованих потоків символів використовуйте BufferedReaderта BufferedWriterкласи.


1
Я шукав такого поглибленого пояснення для Java io. Дуже дякую.
Аріф Реза

14

Ну, це питання на думку будь-кого, хто починає працювати над пакетом java.io. Щоб відповісти на запитання, InputStreamReader та BufferedReader представляють лише об'єкти Java (в них немає нічого особливого), але вони створені для операцій io, таких як читання та запис із / на різні входи / виходи, такі як файл, об'єкт тощо.

Тепер давайте підходимо до черги

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

InputStreamReader - це клас для читання вхідного потоку байтів, але читати кожен байт - дорога операція, тому ми обгортаємо його навколо BufferedReader, щоб він буферизувався (що є шаблоном декоратора)

Отже, що станеться ще до того, як ви почнете читати, bufferedReader збереже частину байтів у реєстрі та під час виконання операції читання. він буде читатися з того місця, яке набагато дешевше, ніж читання з консолі / файлу. Але у випадку InputStreamReader, коли ви виконуєте операцію читання кожного разу, коли відбувається операція доступу до диска


+1, але я б віддав перевагу, якби додав посилання на посилання для декоратора інформації, і кожен раз, коли відбувається операція доступу до диска
shareef

Останній параграф добре підсумовує переваги. Дякую тобі за це.
Dave Voyles

3

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

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


Дякую за відповідь. Але питання, яке мені спало на думку, полягає в тому, що ви маєте на увазі під потоковими даними? Plz це детально розробіть.
користувач122345656

1
Вибачте за пізню відповідь. Якщо ви уявляєте простий приклад файлу розміром 10 Мб на сервері. Сервер має повний файл, але він не може відправити весь файл одним пакетом. Натомість файл розбивається на кінцеву кількість блоків. Потім кожен блок надсилається на віддалений комп’ютер і збирається знову. Для потокової передачі даних в реальному часі застосовується та сама теорія. Але сервер приймає дані в реальному часі і відправляє їх як streamпакети. Потім віддалений комп’ютер зберігає кожен пакет у буфері. Віддалений комп'ютер зчитує дані зі свого буфера і створює, скажімо, відео з цього. Сподіваюся, це допоможе!
PGallagher,

1

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

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

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

Ви можете прочитати посилання для кращого розуміння. Сподіваюся, це допоможе !.
Що таке буфер в Java,
введіть тут опис посилання

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