Понятие «поток» происходит от концепции канала в UNIX. В UNIX канал — это непрерывный поток байтов, используемый для реализации связи между программами или процессами, а также для чтения и записи периферийных устройств, внешних файлов и т. д. Он скрывает детали обработки данных в реальном устройстве ввода-вывода. Поток должен иметь источник и пункт назначения, которыми могут быть определенные области памяти компьютера, файлы на диске или даже URL-адрес в Интернете. Направление потока имеет важное значение. В зависимости от направления потока поток можно разделить на две категории: входной поток и выходной поток. Фактически ввод/вывод предназначен для памяти. Фактически, источник и пункт назначения потока можно просто рассматривать как производителей и потребителей байтов. Для входного потока вам не нужно заботиться о его источнике, пока вы просто читаете данные из потока и для входного потока. Выходной поток также может не знать о своем назначении и просто записывать данные в поток.
а. Поток: набор упорядоченных последовательностей данных.
b Поток байтов: наименьшая единица данных в потоке данных — это байты.
c. Поток символов: наименьшая единица данных в потоке данных — это символ.
1. Классы в пакете java.io соответствуют двум типам потоков.
Один тип потока читает или записывает непосредственно из указанного места (например, из файла на диске или из области памяти). Этот тип потока называется потоком узла, а другие потоки называются потоками фильтрации (потоками упаковки).
Фильтрация потоков. Некоторые потоки могут получать байты из файлов и других источников, а другие потоки могут объединять байты в более полезные типы данных. Конструктор, который передает существующий поток в другой поток и объединяет два потока. Объединенный поток называется фильтрованным потоком. Входной поток фильтра часто использует другие входные потоки в качестве источника входных данных. После фильтрации или обработки он предоставляется пользователю в виде нового входного потока. Выходной поток фильтра аналогичен. Мы редко используем один класс для создания объекта потока, а вместо этого обеспечиваем желаемую функциональность путем наложения нескольких объектов (т. е. шаблона проектирования декоратора).
Часто используемые потоки ввода и вывода Java фактически наследуются от четырех абстрактных классов, а именно:
На основе однобайтового класса InputStream, OutputStream (байт-ориентированный ввод-вывод).
Классы чтения и записи на основе двухбайтовых кодовых единиц Юникода (символьный ввод-вывод)
Как только входной поток открыт, программа может последовательно считывать данные из входного потока. Процесс чтения/записи данных из входного потока обычно выглядит следующим образом: открыть канал потока --> прочитать/записать информацию --> закрыть канал потока.
На платформе Java существует два способа получить тип кодировки символов локальной платформы:
(a) System.getProperty("file.encoding");
(б) Кодировка cs=Charset.defaultCharset();
Все входные и выходные потоки можно разделить на байтовые (входные, выходные) потоки и символьные (входные, выходные) потоки. Те, которые обрабатывают байты, в основном представляют собой серии (OutputStream/InputStream), а те, которые обрабатывают символы, — это в основном (Reader/Write). ) ряд
2. Байт-ориентированные входные потоки (серия InputStream). Эти классы можно подключить к объектам FileInputStream для предоставления полезных интерфейсов:
ByteArrayInputStream: использовать буфер в памяти в качестве входного потока.
StringBufferInputStream (устарело в java1.1): используйте объект String в качестве InputStream, а базовая реализация использует StringBuffer.
FileInputStream: используйте файл в качестве InputStream для реализации операции чтения файла (имя файла, файл, объект FileDescriptor).
PipedInputStream: реализует концепцию канала, в основном используемую в потоках (в качестве источника данных в нескольких процессах).
SequenceInputStream: объединение нескольких входных потоков в один входной поток.
Байт-ориентированные потоки вывода (серия OutputStream) можно подключить к объектам FilterOutputStream для предоставления полезных интерфейсов:
ByteArrayOutputStream: создание буфера в памяти, сохранение информации в буфере в памяти и инициализация размера буфера (необязательно).
FileOutputStream: хранить информацию в файле (имя файла, файл, FileDescriptor).
PipedOutputStream: реализует концепцию канала, в основном используемую в потоках (указывает назначение данных для многопоточности).
3. Соответствующая серия (Чтение/Письмо) :
Reader: соответствует InputStream, адаптер InputStreamReader.
Writer: соответствует OutputStream, а адаптер — OutputStreamWriter.
FileReader: соответствует FileOutputStream.
FileWriter: соответствует FileOurputStream.
StringReader: нет соответствующего класса
StringWriter: соответствует ByteArrayInputStream.
CharArrayReader: соответствует ByteArrayOutputStream.
CharArrayWriter: соответствует ByteArrayOutputStream.
PipedReader: соответствует PipedInputStream.
PipedWriter: соответствует PipedOutputStream.
4. Преобразование между двумя неограниченными потоками ( с использованием класса адаптера)
InputStreamReader и OutputStreamReader: преобразуют байтовый поток в символьный поток.
InputStreamReader — это мост от потока байтов к потоку символов: он читает байты, используя указанную кодировку, и декодирует их в символы. Используемый набор символов может быть указан по имени или задан явно, либо он может принимать набор символов платформы по умолчанию.
OutputStreamWriter — это мост от потока символов к потоку байтов: символы, записываемые в поток, могут быть закодированы в байты с использованием указанной кодировки. Используемый набор символов можно указать по имени или указать явно, в противном случае будет принят набор символов платформы по умолчанию.
5. Считайте данные из InputStream через FilterInputStream :
DataInputStream: чтение данных базового типа (int, char, long и т. д.) из потока.
BufferedInputStream: используйте буфер, чтобы избежать необходимости каждый раз выполнять фактическую операцию чтения.
LineNumberInputStream: запишет количество строк во входном потоке, а затем вызовет getLineNumber() и setLineNumber(int).
PushbackInputStream: используется редко, обычно используется для разработки компиляторов.
Запишите в OutputStream через FilterOutputStream:
DataIOutputStream: данные базового типа (int, char, long и т. д.) могут выводиться в поток в соответствии с методом трансплантации.
BufferedOutputStream: используйте буфер, чтобы избежать фактической записи каждый раз, когда вы отправляете данные.
PrintStream: создает форматированный вывод, где DataOutputStream обрабатывает хранение данных, а PrintStream обрабатывает отображение.
6. Изменить поведение потока
Хотя BufferedOutputStream является подклассом FilterOutputStream, BufferedWriter не является подклассом FilterWriter (FilterWriter — абстрактный класс и не имеет подклассов).
Для DataInputStream нет соответствующего класса. Используйте DataInputStream, если вместо этого вы не используете BufferedReader, когда хотите использовать readLine().
BufferedReader: соответствует BufferedInputStream.
LineNumberReader: соответствует LineNumberInputStream.
PushBackReader: соответствует PushbackInputStream.
BufferedWrite: соответствует BufferedOutStream.
PrintWrite: соответствует PrintStream.
7. Самонезависимый класс: RandomAccessFile.
Этот класс подходит для файлов, состоящих из записей известного размера. В дополнение к реализации интерфейсов DataInput и DataOutput (DataInputStream и DataOutputStream также реализуют эти два интерфейса), RandomAccessFile является полностью независимым классом. Он имеет и другие типы ввода-вывода. различное поведение, могут перемещаться вперед и назад внутри файла и являются производными непосредственно от Object.
Операции чтения и записи файлов можно выполнять с помощью объекта RandomAccessFile.
При создании объекта вы можете указать тип открываемого файла: r — только для чтения; w — только для записи; rw может читать и писать;
Вы можете перейти непосредственно к указанному месту в файле.
Большая часть (но не все) функций RandomAccessFile заменена файлами отображения хранилища nio.