1.Что такое ИО
Операции ввода-вывода в Java в основном относятся к использованию Java для операций ввода и вывода. Все механизмы ввода-вывода Java основаны на потоках данных для ввода и вывода. Эти потоки данных представляют собой текущую последовательность символов или байтовых данных. Потоки ввода-вывода Java предоставляют стандартные методы чтения и записи данных. Любой объект в Java, представляющий источник данных, предоставляет методы для чтения и записи своих данных в поток данных.
Java.io — это основной пакет для большинства классов ввода-вывода, ориентированных на поток данных. Кроме того, Java также обеспечивает поддержку блочной передачи, а блочный ввод-вывод используется в базовой библиотеке java.nio.
Преимущество потокового ввода-вывода в том, что он прост и удобен в использовании, но недостатком является то, что он менее эффективен. Блок ввода-вывода очень эффективен, но программирование сложнее.
Модель ввода-вывода Java:
Модель ввода-вывода в Java очень хороша. Она использует шаблон Decorator для разделения потоков по функциям. Вы можете динамически собирать эти потоки для получения необходимых вам функций. Например, если вам нужен буферизованный входной поток файлов, вам следует использовать комбинацию FileInputStream и BufferedInputStream.
2. Основные понятия потока данных
Поток данных представляет собой набор непрерывных данных, точно так же, как поток воды в водопроводе. Вода подается постепенно на один конец водопровода, а на другом конце водопровода наблюдается непрерывный поток. воды. Программа записи данных может записывать данные в конвейер потока данных сегмент за сегментом. Эти сегменты данных будут последовательно формировать длинный поток данных. Для программ чтения данных сегментация потока данных во время записи не может быть видна. Данные любой длины могут быть прочитаны каждый раз, но сначала могут быть прочитаны только предыдущие данные, а затем последующие данные. Независимо от того, записываются ли данные несколькими пакетами или записываются целиком сразу, эффект при чтении будет абсолютно одинаковым.
«Поток — это источник или место назначения данных, хранящихся на диске или другом периферийном устройстве».
Существует три способа хранения данных на компьютере: внешнее хранилище, память и кеш. Например, жесткий диск, магнитный диск, USB-накопитель и т. д. на компьютере являются внешними запоминающими устройствами. На компьютере есть карта памяти, а кэш находится в процессоре. Внешнее хранилище имеет наибольшую емкость, за ним следует память и, наконец, кэш. Однако чтение данных из внешнего хранилища является самым медленным, за ним следует память, а самым быстрым является кэш. Вот краткое описание чтения данных из внешней памяти в память и записи данных из памяти во внешнюю память. Для понимания памяти и внешнего хранилища мы можем просто понимать его как контейнер, то есть внешнее хранилище — это контейнер, а память — это другой контейнер. Итак, как считать данные из контейнера внешнего хранилища в контейнер памяти и как сохранить данные из контейнера памяти во внешнее хранилище?
В библиотеке классов Java часть ввода-вывода очень велика, поскольку она охватывает широкий спектр полей:
Стандартный ввод и вывод, файловые операции, потоки данных в сети, строковые потоки, потоки объектов, потоки zip-файлов и т. д. В Java абстракция ввода и вывода называется потоком, который похож на водопровод, соединяющий два контейнера. Чтение данных из внешней памяти в память называется входным потоком, а запись данных из памяти во внешнюю память называется выходным потоком.
Поток — очень яркая концепция. Когда программе необходимо прочитать данные, она открывает поток к источнику данных. Этим источником данных может быть файл, память или сетевое соединение. Аналогично, когда программе необходимо записать данные, она открывает поток по назначению.
Основные понятия вкратце заключаются в следующем:
Упорядоченная последовательность байтов с начальной и конечной точкой. Включая входной поток и выходной поток.
2) Входной поток:Программа считывает источник данных из входного потока. Источники данных включают внешний мир (клавиатура, файлы, сеть...), который является каналом связи, который считывает источник данных в программу.
Цель использования потоков данных — сделать вывод и ввод независимыми от устройства.
Входному потоку не важно, с какого устройства поступает источник данных (клавиатура, файл, сеть).
Выходной поток не заботится о том, для какого устройства предназначены данные (клавиатура, файл, сеть).
3. Стандартный ввод-вывод
Программы Java могут обмениваться краткой информацией с внешним миром через параметры командной строки. В то же время здесь также оговаривается, как обмениваться информацией со стандартными устройствами ввода и вывода, такими как клавиатуры и мониторы. Через файлы можно обмениваться информацией в любой форме с внешним миром.
1. Параметры командной строкиРезультаты запуска:
args[0] — это <Java>
args[1] равен <C>
args[2] — это <VB>
Стандартный поток данных, поставляемый с системой Java: java.lang.System:
Уведомление:
(1) Класс System не может создавать объекты и может напрямую использовать только три своих статических члена.
(2) Всякий раз, когда выполняется основной метод, автоматически генерируются три вышеуказанных объекта.
1) Стандартный поток вывода System.out
System.out выводит данные на стандартное устройство вывода , а его тип данных — PrintStream. метод:
2) Стандартный поток ввода System.in
System.in считывает данные стандартного устройства ввода (получает данные из стандартного ввода, обычно с клавиатуры), а его тип данных — InputStream. метод:
3) Стандартный поток ошибок
System.err выводит стандартную ошибку , а ее тип данных — PrintStream. Пожалуйста, обратитесь к API для получения подробных инструкций.
Стандартный вывод вызывает метод println через System.out для вывода параметров и переноса новых строк, тогда как метод print выводит параметры, но не переносит новые строки. Метод println или print реализует несколько методов вывода базовых типов данных посредством перегрузки, включая типы выходных параметров boolean, char, int, long, float и double. В то же время перегружаются и методы, типы выходных параметров которых — char[], String и Object. Среди них методы print(Object) и println(Object) будут вызывать метод toString параметра Object во время выполнения.
общественный класс StandardInputOutput {
public static void main(String args[]) {
Строка с;
//Создаем устройство чтения буфера для построчного чтения данных с клавиатуры
InputStreamReader ir = новый InputStreamReader(System.in);
BufferedReader in = новый BufferedReader (IR);
System.out.println("Система Unix: ctrl-d или ctrl-c для выхода"
+ "/nСистема Windows: ctrl-z выход");
пытаться {
//Считываем одну строку данных и стандартно выводим ее на монитор
s = in.readLine();
// Если во время работы метода readLine() возникает ошибка ввода-вывода, будет выброшено исключение IOException.
в то время как (s != ноль) {
System.out.println("Читать: " + s);
s = in.readLine();
}
// Закрываем буферизованный ридер
в.закрыть();
} catch (IOException e) { // Перехватываем любые исключения ввода-вывода.
е.printStackTrace();
}
}
}
4.java.IO иерархическая архитектура
Самое важное во всем пакете Java.io — это 5 классов и интерфейс. Пять классов относятся к File, OutputStream, InputStream, Writer и Reader; один интерфейс относится к Serializable. Как только вы освоите эти основные операции ввода-вывода, вы получите предварительное представление о системе ввода-вывода в Java.
Java I/O в основном включает в себя следующие уровни, включая три части:
1. Основная часть потоковой части IO;
2. Непотоковая часть в основном включает в себя некоторые классы, которые помогают потоковой части, например: класс File, класс RandomAccessFile и класс FileDescriptor;
3. Другие классы — классы, связанные с безопасностью в части чтения файлов, такие как класс SerializablePermission, и классы файловой системы, связанные с локальной операционной системой, такие как класс FileSystem, класс Win32FileSystem и класс WinNTFileSystem.
Основные классы следующие:
1. Файл (характеристики файла и управление им): используется для описания информации о файлах или каталогах, например создания новых каталогов, изменения имен файлов, удаления файлов, определения пути к файлу и т. д.
2. InputStream (операция двоичного формата): абстрактный класс, операция ввода на основе байтов, является родительским классом для всех входных потоков. Определяет общие характеристики, которыми обладают все входные потоки.
3. OutputStream (операция двоичного формата): абстрактный класс. Операции вывода на основе байтов. Является родительским классом для всех выходных потоков. Определяет общие характеристики, которыми обладают все выходные потоки.
Символы в Java соответствуют стандарту Unicode. Один символ имеет длину 16 бит, то есть один символ представлен двумя байтами. Для этого в JAVA были введены потоки обработки символов.
4. Читатель (операция формата файла): абстрактный класс, операция символьного ввода.
5. Writer (операция формата файла): абстрактный класс, операция вывода символов.
6. RandomAccessFile (случайная операция с файлом): он имеет богатые функции и может выполнять операции доступа (ввода и вывода) из любого места в файле .
Архитектура потока ввода-вывода в Java выглядит следующим образом:
5. Класс непотоковых файлов. Класс файлов.
}
Описание: Методы класса File:
(1) существует() проверяет, существует ли указанный файл или каталог на диске.
(2) mkdir() создает каталог, указанный файловым объектом (однослойный каталог).
(3) createNewFile() создает файл, указанный файловым объектом.
(4) list() возвращает все строки имен файлов в каталоге.
6. Библиотека классов потоков Java.IO
Пакет java.io содержит все классы, необходимые для потокового ввода-вывода. В пакете java.io есть четыре основных класса: классы InputStream, OutputStream, Reader и Writer, которые обрабатывают потоки байтов и потоки символов соответственно:
Базовый поток данных ввода/вывода
ввод/вывод
поток байтов
поток символов
входной поток
Входной поток
Читатель
выходной поток
Выходной поток
Писатель
На их основе произошли различные другие варианты потоков в Java:
В версии JDK1.4 появилась новая библиотека классов ввода-вывода, которая находится в пакете java.nio. Новая библиотека классов ввода-вывода использует каналы и буферы для повышения эффективности операций ввода-вывода.
В пакете java.io java.io.InputStream представляет поток ввода байтов, а java.io.OutputStream представляет поток вывода байтов, который находится на верхнем уровне пакета java.io. Оба класса являются абстрактными классами, а это означает, что они не могут быть созданы и должны быть подклассами для достижения определенных функций.
1. Конкретная классификация потоков ввода-вывода1. Общая классификация по типу ввода-вывода:
1. Память 1) Чтение и запись данных из/в массив памяти: CharArrayReader, CharArrayWriter, ByteArrayInputStream, ByteArrayOutputStream.
2) Чтение и запись данных из/в строки памяти StringReader, StringWriter, StringBufferInputStream.
2. Конвейер Pipe реализует ввод и вывод конвейера (межпроцессное взаимодействие): PipedReader, PipedWriter, PipedInputStream, PipedOutputStream.
3.Файловый файловый поток . Чтение и запись файлов: FileReader, FileWriter, FileInputStream, FileOutputStream.
4. Ввод и вывод объекта ObjectSerialization : ObjectInputStream, ObjectOutputStream.
5. Поток данных DataConversion считывает и записывает в соответствии с базовыми типами данных (обрабатываемые данные представляют собой базовые типы Java (такие как логические значения, байты, целые числа и числа с плавающей запятой)): DataInputStream, DataOutputStream.
6.Печать включает удобные методы печати: PrintWriter, PrintStream.
7. Буферизация кэширует данные при чтении или записи для уменьшения количества операций ввода-вывода: BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream.
8. Фильтрация потока фильтрации , фильтрация при чтении или записи данных: проход FilterReader, FilterWriter, FilterInputStream, FilterOutputStream.
9.Конкатенация объединяет входные данные и соединяет несколько входных потоков в один входной поток: SequenceInputStream.
10. Подсчет строк при чтении данных: LineNumberReader, LineNumberInputStream.
11.Peeking Ahead выполняет предварительное чтение через механизм кэширования: PushbackReader, PushbackInputStream
12. Преобразование между байтами и символами преобразует поток байтов в поток символов в соответствии с определенными стандартами кодирования/декодирования или выполняет обратное преобразование (класс преобразования потока в устройство чтения, записи): InputStreamReader, OutputStreamWriter.
2. Классификация по источнику данных (назначению):
1. Файл: FileInputStream, FileOutputStream, FileReader, FileWriter.
2. byte[]: ByteArrayInputStream, ByteArrayOutputStream
3. Char[]: CharArrayReader, CharArrayWriter.
4. Строка: StringBufferInputStream, StringReader, StringWriter.
5. Поток сетевых данных: входной поток, выходной поток, считыватель, писатель.
7. Поток байтов InputStream/OutputStream
InputStream — это поток ввода байтов. Он сам по себе является абстрактным классом и должен полагаться на свои подклассы для реализации различных функций. Этот абстрактный класс является суперклассом всех классов, которые представляют потоки ввода байтов. Потоки, унаследованные от входных данных InputStream, в программу, а единицей данных являются байты (8 бит);
InputStream — это класс, используемый для ввода байтовых данных, поэтому класс InputStream предоставляет три перегруженных метода чтения в классе Inputstream:
(1) public абстрактное int read(): считывает байт данных, возвращаемое значение представляет собой значение типа int со старшими битами, заполненными 0. Если возвращаемое значение = -1, это означает, что ни один байт не был прочитан и работа чтения завершена.
(2) public int read(byte b[]): прочитайте байты данных длиной b и поместите их в массив b. Возвращаемое значение — это количество прочитанных байтов. Этот метод фактически реализуется путем вызова следующего метода (3) public int read(byte b[ ], int off, int len): Считайте до len байтов данных из входного потока и сохраните их со смещением off в б массив.
(4) public int Available(): возвращает количество байтов, которые можно прочитать во входном потоке. Примечание. Если ввод заблокирован, текущий поток будет приостановлен. Если объект InputStream вызывает этот метод, он вернет только 0. Чтобы этот метод был полезен, он должен быть вызван объектом подкласса, который наследует класс InputStream.
(5) public long jump(long n): игнорировать n байтов во входном потоке, возвращаемое значение — это количество фактически проигнорированных байтов, пропустить несколько байтов для чтения (6) public int close(): мы после использования поток, который мы открыли, должен быть закрыт.
Основные подкатегории:
1) FileInputStream использует файл в качестве входного потока для реализации операции чтения файла. 2) ByteArrayInputStream: использует буфер в памяти в качестве входного потока. 3) StringBufferInputStream: использует объект String в качестве входного потока.
4) PipedInputStream: реализует концепцию канала, в основном используемую в потоках. 5) SequenceInputStream: объединяет несколько входных потоков в один входной поток.
Основные подкатегории:
1) ByteArrayOutputStream: хранить информацию в буфере в памяти.
2) FileOutputStream: хранить информацию в файле.
3) PipedOutputStream: реализует концепцию канала, в основном используемую в потоках.
4) SequenceOutputStream: объединение нескольких потоков OutStream в один OutStream.
Определение конца потока: когда возвращаемое значение метода read() равно -1, когда возвращаемое значение readLine() равно нулю;
3. Поток ввода файла: класс FileInputStream.FileInputStream может использовать метод read() для чтения по одному байту за раз и возвращать его как тип int или использовать метод read() для чтения в массив байтов. Сколько байтов считывается в зависимости от количества элементов в массиве. массив байтов. В процессе чтения или записи всего файла такой массив байтов обычно используется в качестве буфера, поскольку такой массив байтов обычно играет промежуточную роль при приеме данных.
Как использовать(2)
FileInputStream in = newFileInputStream («d: /abc.txt»);
Пример программы:
Отображение содержимого программы InputFromFile.java на мониторе
общественный класс TestFile {
public static void main(String args[]) выдает IOException {
пытаться{
FileInputStream rf = новый FileInputStream («InputFromFile.java»);
int n=512 байтовый буфер[]=новый байт[n];
while((rf.read(buffer,0,n)!=-1)&&(n>0)){
System.out.println(новая строка(буфер));
}
Система.out.println();
рф.закрыть();
} catch(IOException IOe){
System.out.println(IOe.toString());
}
}
}
Класс FileOutputStream используется для обработки потоков данных, которые используют файлы в качестве мест назначения вывода данных; это строка, представляющая имя файла, которая также может быть объектом File или FileDescriptor.
Существует два способа создания объекта файлового потока:
Способ 1:
Файл f=новый файл ("d:/myjava/write.txt");
FileOutputStream out = новый FileOutputStream (f);
Способ 2:
FileOutputStream out = новый FileOutputStream («d:/myjava/write.txt»);
Способ 3: Конструктор принимает объект FileDescriptor() в качестве параметра.
FileDescriptor() fd=новый FileDescriptor();
FileOutputStream f2 = новый FileOutputStream (fd);
Метод 4: Конструктор принимает имя файла в качестве первого параметра и логическое значение в качестве второго параметра.
FileOutputStream f = новый FileOutputStream («d:/abc.txt», true);
Примечание: (1) При записи данных в файл, если файл уже существует, существующий файл будет перезаписан. (2) Когда операция чтения/записи завершается, следует вызвать метод close, чтобы закрыть поток;
}
общественный класс TestFile {
public static void main(String args[]) выдает IOException {
пытаться {
Файл inFile = новый файл("copy.java");
Файл outFile = новый файл («copy2.java»);
FileInputStream finS = новый FileInputStream(inFile);
FileOutputStream foutS = новый FileOutputStream (outFile);
интервал с;
while ((c = finS.read()) != -1) {
foutS.write(с);
}
finS.закрыть();
foutS.close();
} catch (IOException e) {
System.err.println("FileStreamsTest: " + e);
}
}
}
Доступ компьютера к внешним устройствам требует много времени. Чем выше частота обращения к внешней памяти, тем больше вероятность того, что процессор будет простаивать. Чтобы уменьшить количество обращений к внешней памяти, за один доступ к периферийному устройству следует читать и записывать больше данных. С этой целью, помимо механизмов чтения и записи, необходимых для обмена данными между программами и узлами потока, следует добавить еще и механизм буферизации. Буферизованный поток означает, что каждому потоку данных выделяется буфер, а буфер — это память, в которой временно хранятся данные. Это может уменьшить количество обращений к жесткому диску и повысить эффективность передачи.
BufferedInputStream: при записи данных в буферизованный поток данные сначала записываются в буфер. После заполнения буфера система сразу отправляет данные на устройство вывода.
BufferedOutputStream: при чтении данных из буферизованного потока система сначала считывает данные из буфера. Когда буфер пуст, система затем считывает данные из устройства ввода в буфер.
Подключите BufferedInputStream к FileInputStream.
FileInputStreamin = newFileInputStream («file1.txt»);
BufferedInputStreambin = newBufferedInputStream (в);
2) Записать память в файл:
Подключите BufferedOutputStream к FileOutputStream.
FileOutputStreamout = newFileOutputStream («file1.txt»);
BufferedOutputStreambin = newBufferedInputStream (выход);
общественный класс ReadWriteToFile {
public static void main(String args[]) выдает IOException {
InputStreamReader sin = новый InputStreamReader(System.in);
BufferedReader bin = новый BufferedReader (грех);
FileWriter out = новый FileWriter("myfile.txt");
BufferedWriter бой = новый BufferedWriter (выход);
Строка с;
while ((s = bin.readLine()).length() > 0) {
bout.write(s, 0, s.length());
}
}
}
8. Поток символов Writer/Reader
Символы в Java соответствуют стандарту Unicode. Один символ имеет длину 16 бит, то есть один символ представлен двумя байтами. Для этого в JAVA были введены потоки обработки символов.
Абстрактный класс для чтения потоков символов. Единственные методы, которые должны реализовывать подклассы, — это read(char[], int, int) и close(). Однако большинство подклассов переопределяют некоторые из определенных здесь методов, чтобы обеспечить большую эффективность и/или дополнительную функциональность.
1) FileReader: соответствует FileInputStream, в основном используется для чтения файлов символов с использованием кодировки символов по умолчанию и имеет три конструктора:
(1) Используйте имя файла в виде строки: FileReader f=new FileReader("c:/temp.txt");
(2) Конструктор принимает объект File в качестве параметра.
Файл f=новый файл("c:/temp.txt");
FileReader f1 = новый FileReader (f);
(3) Конструктор принимает объект FileDescriptor в качестве параметра.
FileDescriptor() fd=новый FileDescriptor()
FileReader f2 = новый FileReader (fd);
(1) Используйте указанный массив символов в качестве параметра: CharArrayReader(char[])
(2) Использовать массив символов в качестве входного потока: CharArrayReader(char[], int, int)
Чтобы прочитать строку, конструктор выглядит следующим образом: public StringReader(String s);
2) CharArrayReader: соответствует ByteArrayInputStream.
3) StringReader: соответствует StringBufferInputStream.
4) Читатель Входного Потока
Считайте байты из входного потока и преобразуйте их в символы: Public inputstreamReader(inputstream is);
5) FilterReader: позволяет фильтровать потоки символов.
защищенный фильтрReader(Reader r);
6) BufferReader: принимает объект Reader в качестве параметра и добавляет к нему буфер символов. Используйте метод readline() для чтения строки.
Публичный BufferReader (Читатель r);
Основные методы:
(1) publicintread()throwsIOException;//Читаем символ, возвращаемое значение — это прочитанный символ
(2) publicintread(charcbuf[])throwsIOException;/*Считайте серию символов в массив cbuf[], и возвращаемое значение — это количество фактически прочитанных символов*/
(3) publicabstractintread(charcbuf[],intoff,intlen)throwsIOException;
/*Читаем len символов и сохраняем их, начиная с нижнего индекса массива cbuf[]. Возвращаемое значение — это фактическое количество прочитанных символов. Этот метод должен быть реализован в подклассе*/.
Абстрактный класс для записи в потоки символов. Единственные методы, которые должны реализовывать подклассы, — это write(char[], int, int),lush() и close(). Однако большинство подклассов переопределяют некоторые из определенных здесь методов, чтобы обеспечить большую эффективность и/или дополнительную функциональность. Его подкатегории следующие:
1) FileWrite: соответствует FileOutputStream и записывает данные типа символов в файл, используя кодировку символов и размер буфера по умолчанию.
Публичная FileWrite (файл f);
2) chararrayWrite: соответствует ByteArrayOutputStream, используя в качестве вывода буфер символов.
Публичный CharArrayWrite();
3) PrintWrite: создание форматированного вывода public PrintWriter (outputstream os);
4) filterWriter: используется для записи потока символов фильтра, защищенного FilterWriter(Writer w);
5) PipedWriter: соответствует PipedOutputStream.
6) StringWriter: нет соответствующего байтового потока.
Основные методы:
(1) publicvoidwrite(intc)throwsIOException; //Записываем младшие 16 бит целочисленного значения c в выходной поток (2) publicvoidwrite(charcbuf[])throwsIOException; //Записываем массив символов cbuf[] в выходной поток ( 3) publicabstractvoidwrite(charcbuf[],intoff,intlen) throwsIOException; //Записываем len символов, начиная с индекса off в массиве символов cbuf[] в поток вывода (4) publicvoidwrite(Stringstr)throwsIOException; //Записываем символы в; string str записываются в выходной поток (5) publicvoidwrite(Stringstr,intoff,intlen)throwsIOException //Записываем len символов, начиная с индекса off в строке str, в выходной поток (6)lush() / /Сбрасываем выходной поток и вывести все буферизованные байты.
(7) close() закрывает поток publicabstractvoidclose() throwsIOException
3. Разница между InputStream и Reader, разница между OutputStream и Writer
public static void main(String args[]) выдает IOException {
System.out.println("В памяти используется кодировка символов Unicode: ");
char c = 'хорошо';
int lowBit=c&0xFF; int highBit=(c&0xFF00)>>8;
System.out.println(""+lowBit+" "+highBit);
Строка s="ОК";
System.out.println("Кодировка символов по умолчанию в локальной операционной системе:");
readBuff(s.getBytes());
System.out.println("Использование кодировки символов GBK:");
readBuff(s.getBytes("GBK"));
System.out.println("Кодировка символов UTF-8:");
readBuff(s.getBytes("UTF-8"));
}
9. Подклассы класса исключений IOException.
1.публичный класс EOFException:
Исключение этого типа генерируется, когда конец файла или конец входного потока достигаются ненормально.
2.публичный класс FileNotFoundException:
Исключение, возникающее, когда файл не может быть найден.
3.публичный класс InterruptedIOException:
Этот тип исключения брошен, когда операция ввода/вывода прерывается.