Ввод/вывод и NIO в JAVA
Проблема ввода-вывода является неизбежной проблемой для любого языка программирования.Можно сказать, что проблема ввода-вывода является основной проблемой всего взаимодействия человека с компьютером, поскольку ввод-вывод является основным каналом для получения и обмена данными между машинами. Информация. В нынешнюю эпоху стремительного роста данных проблема ввода-вывода особенно актуальна и может легко стать узким местом в производительности.
Что такое ввод-вывод
/ O? Или ввод / вывод? Относится к интерфейсу между компьютером и остальным внешним миром или с компьютерной программой. Это очень важно для любой компьютерной системы, и, следовательно, в зависимости от всего ввода / вывода на самом деле встроена в операционную систему. Отдельные программы обычно позволяют системе сделать большую часть работы для них.
-
I
: отжесткий дискчитать содержимое вОЗУсередина -
O
: отОЗУчитать содержимое вжесткий дисксередина
в некоторых случаях
I/O
Отсутствует взаимодействие с жестким диском, такое как потоковая передача по каналу, которая включает связь между двумя потоками. Сам канал представляет собой циклический буфер, выделенный в памяти, который может использоваться только двумя соединяющими его потоками.
Классы операций ввода-вывода в Java находятся в пакетеjava.io
Ниже, вероятно, около 80 классов, но эти классы можно разделить на три группы.
- Байтовый интерфейс ввода-вывода:
InputStream
иOutputStream
- Интерфейс ввода-вывода на основе персонажей:
Writer
иReader
- Интерфейс ввода-вывода на основе дисковых операций:
File
Кроме того, под каждым интерфейсом есть свои классы-оболочки, которые используются дляорнамент, добавить в него какие-то функции, да и Java-сложность ввода-вывода тоже тут, да и код для создания классов в разных режимах оформления тоже разный.
Байтовые операции
InputStream
Роль используется для представления тех классов, которые генерируют входные данные из различных источников данных, включая
- байтовый массив
- Строковый объект
- документ
- Трубы работают так же, как настоящие трубы, с входом с одного конца и выводом с другого конца.
- другие источники данных, такие как
Internet
серединаSocket
соединять
InputStream
диаграмма классов,OutputStream
Диаграмма классов похожа на эту
своего рода | Функции | Параметры конструктора | как пользоваться |
---|---|---|---|
ByteArrayInputStream |
Позволяет использовать буферы памяти в качествеInputStream использовать |
буфер, из которого берутся байты | как источник данных: объедините его сFilterInputStream объекты связаны, чтобы обеспечить полезный интерфейс |
StringBufferInputStream |
Преобразовать строку вInputStream
|
String, базовая реализация фактически используетStringBuffer
|
как источник данных: объедините его сFilterInputStream Объекты связаны, чтобы обеспечить полезные интерфейсы |
FileInputStream |
для чтения информации из файла | Строка, представляющая имя файла, файл илиFileDescriptor объект |
как источник данных он сочетается сFilterInputStream Объекты связаны, чтобы обеспечить полезные интерфейсы |
PipedInputStream |
Для написанияPipedOutputStream Объем данных для реализации концепции конвейера |
PipedOutputStream |
В качестве многопоточного источника данных: объедините его сFilterInputStream Объекты связаны, чтобы обеспечить полезные интерфейсы |
FilterInputStream |
абстрактный класс, как интерфейс для декораторов, для другихInputStream Обеспечьте полезные функции |
Используйте фильтры, чтобы добавить полезные свойства и полезные интерфейсы
Библиотека классов ввода-вывода в Java требует комбинации множества различных функций, что и является причиной шаблона декоратора. И это также причина, по которой в библиотеке классов ввода-вывода java есть класс Filter (фильтр), который является базовым классом всех декоративных классов.
своего рода | Функции |
---|---|
BufferedInputStream |
С его помощью можно предотвратить взаимодействие с диском при каждом чтении и использовать буфер для чтения фиксированного значения за один раз, а затем выполнить операцию записи на диск, сократив количество взаимодействий с диском. ускорить |
DataInputStream |
Позволяет приложениям считывать основные типы данных Java из базового потока ввода машинно-независимым способом. |
Например, просто используйте фильтр для чтения содержимого файла и вывода, пример выглядит следующим образом:
public static void main(String[] args) throws IOException {
InputStream inputStream = new BufferedInputStream(new FileInputStream("/Users/hupengfei/Downloads/a.sql"));
byte[] buffer = new byte[1024];
while ( inputStream.read(buffer)!=-1){
System.out.println(new String(buffer));
}
inputStream.close();
}
Скопируйте пример файла:
public static void main(String[] args) throws IOException {
InputStream inputStream =new BufferedInputStream(new FileInputStream("/Users/hupengfei/Downloads/leijicheng.png"));
OutputStream outputStream =new BufferedOutputStream(new FileOutputStream("/Users/hupengfei/Downloads/fuzhi.png"));
byte [] buffer = new byte[1024];
while (inputStream.read(buffer)!=-1){
outputStream.write(buffer);
}
outputStream.flush();
inputStream.close();
outputStream.close();
}
Если вы хотите использовать
BufferedOutputStream
Если вы пишете в файл, не забудьте вызвать после записи буфера.flush()
Очистить буфер. Принудительно записать данные в буфер. В противном случае данные могут быть не записаны.
символьные операции
Будь то дисковая или сетевая передача, наименьшая единица хранения — байты, а не символы, поэтому операции ввода-вывода — это байты, а не символы, но почему интерфейс ввода-вывода работает с символами? Это связано с тем, что данные, которыми обычно оперируют в наших программах, имеют форму символов.Для удобства работы, конечно, должен быть предусмотрен интерфейс ввода-вывода для непосредственной записи символов.
Или старые правила, давайте посмотрим наReader
Диаграмма классов , соответствующий поток байтовInputStream
один из нихInputStreamReader
это возможноInputStream
преобразовать вReader
То есть перевести байты в символы. почему дизайнReader
иWriter
, в основном для интернационализации. Предыдущий поток байтов поддерживает только 8-битные потоки байтов и не может хорошо обрабатывать 16-битные символы Unicode. Поскольку Unicode используется для интернационализации символов, он добавленReader
иWriter
Он предназначен для поддержки Unicode во всех операциях ввода/вывода.
В некоторых случаях ориентированный байтовый потокInputStream
иOutputStream
правильное решение, особенно вjava.util.zip
Библиотеки классов ориентированы на байты, а не на символы. Поэтому самое разумное, что можно сделать, это попытаться расставить приоритеты в использованииReader
иWriter
, когда программа не скомпилируется, нам приходится использовать библиотеку, ориентированную на байты.
Или напишите связанный простой пример чтения файла
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("/Users/hupengfei/Downloads/a.sql"));
String date;
StringBuilder stringBuilder = new StringBuilder();
while ((date = bufferedReader.readLine()) != null){
stringBuilder.append(date +"\n");
}
bufferedReader.close();
System.out.println(stringBuilder.toString());
}
перечислить
readLine()
способ добавить новую строку, потому чтоreadLine()
Разрывы строк удаляются автоматически
Что такое НИО
существуетJDK1.4
Класс NIO был добавлен в , мы также можем назвать его новым вводом-выводом. NIO был создан, чтобы позволить Java-программистам реализовывать высокоскоростной ввод-вывод без написания собственного собственного кода. NIO может значительно повысить скорость, перенеся наиболее трудоемкие операции ввода-вывода (например, заполнение и выборку буферов) обратно в операционную систему.
Увеличение скорости происходит за счет использования структур, которые ближе к тому, как операционная система выполняет ввод-вывод: каналы и буферы.
Каналы и буферы — это основные объекты в NIO, и они используются почти во всех операциях ввода-вывода. Канал является аналогом потока в исходном пакете ввода/вывода. Данные в любом месте (из любого места) должны проходить через объект Channel. Буфер — это, по сути, объект-контейнер. Все объекты, отправляемые в канал, должны быть предварительно помещены в буфер Buffer.
Мы можем думать о них как об угольной шахте, канал — это шахта, содержащая уголь (данные), а буфер — это вагонетка, которая отправляется в шахту, вагонетка возвращается полная угля, и мы получаем уголь из вагонетки. То есть мы напрямую не взаимодействуем с каналом, мы взаимодействуем только с буфером.
Введение в буфер
Буфер — это объект, который содержит некоторые данные для чтения или данные для передачи. Объект Buffer добавлен в NIO, что отражает важное отличие от предыдущего ввода-вывода. В потоковом вводе-выводе мы взаимодействуем с данными напрямую через потоковые объекты, но в NIO наше взаимодействие с данными должно проходить через буфер.
Буфер — это, по сути, массив. Обычно это массив байтов, но могут использоваться и другие виды массивов. Но буфер — это больше, чем просто массив, буфер обеспечивает структурированный доступ к данным, а также отслеживает процесс чтения и записи в системе.
Далее мы можем посмотреть наBuffer
Связанные классы реализации
КаждыйBuffer
классыBuffer
Экземпляр интерфейса. КромеByteBuffer
,КаждыйBuffer
Все классы имеют одни и те же операции, различаются только типы данных, которые они обрабатывают. Поскольку большинство стандартных операций ввода-вывода используютByteBuffer
, так что у него есть все операции с общим буфером, а также некоторые уникальные операции.
ByteBuffer
является единственным буфером, взаимодействующим непосредственно с каналом, то есть буфером, который может хранить необработанные байты. когда мы смотрим наByteBuffer
Когда вы получаете исходный код, вы обнаружите, что он создаетByteBuffer
объект, а также имеет набор методов для вывода и чтения данных в необработанных байтах или примитивных типах данных. Однако невозможно вывести или прочитать объекты, даже объекты, являющиеся строками. Это низкоуровневый способ обработки, но это нормально, поскольку это более эффективный способ отображения в большинстве операционных систем.
Введение в канал (канал)
Channel
это объект, через который буфер может читать и записывать данные. По сравнению с исходным вводом-выводом канал подобен потоку. Как упоминалось ранее,Channel
Он не взаимодействует с данными. Но он немного отличается от потока, то есть канал двунаправленный, а поток может быть только односторонним (только InputStream или OutputStream), но канал может использоваться для чтения, записи или и для чтения, и для записи.
В предыдущем вводе-выводе изменены три класса, которые можно использовать для генерацииFileChannel
объект. Три классаFileInputStream
,FileOutputStream
и для чтения и для записиRandomAccessFile
.
Давайте создадимFileChannel
пример.
FileChannel in = new FileInputStream("fileName").getChannel();
использование NIO
Я приведу простой пример, чтобы продемонстрировать, как использовать NIO для копирования файлов. Как упоминалось выше, NIO работает с буфером и каналом, который взаимодействует с буфером, поэтому теперь нам нужно иметь два объекта, один из которыхBuffer
иChannel
.
public static void main(String[] args) throws IOException {
//获取读通道
FileChannel in = new FileInputStream("/Users/hupengfei/Downloads/hu.sql").getChannel();
//获取写通道
FileChannel out = new FileOutputStream("/Users/hupengfei/Downloads/a.sql").getChannel();
//为缓冲器进行初始化大小
ByteBuffer byteBuffer =ByteBuffer.allocate(1024);
while (in.read(byteBuffer)!=-1){
//做好让人读的准备
byteBuffer.flip();
out.write(byteBuffer);
//清除数据
byteBuffer.clear();
}
}
Как только вы захотите прочитать данные из буфера, вызовите метод буфераflip()
метод, делая его готовым для чтения байтов кем-то другим. Затем после записи данных будет вызван буфер.clear()
метод переставляет все внутренние указатели так, чтобы буфер находился в другомread()
Будьте готовы принимать данные во время работы. Затем данные будут непрерывно считываться из исходного файла в целевой файл.
clear()
Этот метод описан в исходном коде, этот метод на самом деле не очищает данные в буфере.
Конечно, описанный выше метод также может быть простым, напрямую соединяя два канала, нужно только позвонитьtransferTo()
метод, это также эффект копирования файлов.
public static void main(String[] args) throws IOException {
FileChannel in = new FileInputStream("/Users/hupengfei/Downloads/hu.sql").getChannel();
FileChannel out = new FileOutputStream("/Users/hupengfei/Downloads/a.sql").getChannel();
in.transferTo(0,in.size(),out);
}
Справочная статья
- Идеи программирования на Java
- Woohoo. IBM.com/developer Я…
- Woohoo. IBM.com/developer Я…