Ввод – Вывод в Java
Меню сайта

Форма входа

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Приветствую Вас, Гость · RSS 19.03.2024, 05:08

Ввод – Вывод в Java

Данный материал посвящен системе ввода - вывода в Java. Система ввода-вывода (input/output, или I/O) информации, реализованные в составе стандартного пакета Java.io. Поддержка ввода-вывода реализован ядром библиотек программного интерфейса (API), а не ключевыми словами языка. Классы библиотек ввода – вывода Java разделены на две части – одни осуществляют ввод, другие вывод. Тем не менее, Java обеспечивает мощную и гибкую поддержку ввода – вывода, когда это касается файлов и сетей.

Потоки


Ввод – вывод в Java осуществляется с помощью так называмых потоков в Java (stream), которая либо порождает, либо принимает информацию. Осуществление ввода – вывода с помощью потоков имеет свои плюсы, потому что поток скрывает все детали низкоуровневых процессов, происходящих с данными непосредственно в устройствах ввода - вывода. Все потоки ведут себя на одинаково, даже несмотря на то, что реальные физические устройства, к которым они подключена, отличаются друг от друга. Таким образом, одни и те же классы и методы ввода – вывода применимы к устройствам разного типа. Это означает, что абстракция входного потока может охватить разные типы ввода: из дискового файла, клавиатуры или сетевого сокета. Аналогично выходной поток может ссылаться на консоль, дисковый файл или сетевое подключение. Потоки – это ясный способ обращения с вводом – выводом без необходимости для вашего кода разбираться с разницей, например между клавиатурой и сетью. Java реализует потоки внутри иерархии классов, определенных в пакете java.io. Java определяет два типа потоков: байтовые и символьные. Байтовые потоки предоставляют удобные средства для управления вводом и выводом байтов. Байтовые потоки используются, например, при чтении и записи бинарных данных. Обычный консольный ввод- вывод идет через байтовые потоки. Символьные потоки предлагают удобные возможности управления вводом и выводом символом. Они используют кодировку Unicode и, таким образом, могут быть интернационализированы. Кроме того, в некоторых случаях символьные потоки более эффективны, чем байтовые.

Классы байтовых потоков

Основные абстрактные классы, от которых наследуют все классы байтового ввода – вывода, - InputStream и OutputStream. Каждый из этих абстрактных классов имеет несколько реальных подклассов, которые управляют различиями между различными устройствами, такими как дисковые файлы, сетевые подключения и даже буферы памяти. Абстрактные классы InputStream и OutputStream переопределяют несколько ключевых методов, которые реализует другие потоковые классы. Два наиболее важных – это read() и write(), которые, соответственно, читают и пишут байты данных. Оба метода обновлены как абстрактные внутри InputStream OutputStream. В классы – наследниках они переопределяются. Классы байтовых потоков перечислены ниже.
Классы байтовых потоков
BufferedInputStream - Буферизированный входной поток
BufferedOutpudStream - Буферизированный выходной поток.
ByteArrayInputStream Входной поток, читающий из массива байт.
ByteAOutputInputStream - Выходной поток, записывающий из массива байт
DataInputStream - Входной поток, записывающий методы для чтения стандартных типов данных Java
DataOutputStream - Выходной поток, включающий методы для записи стандартных типов Java.
FileInputStream - Выходной поток, читающий из файла
FileOutputStream - Входной поток, записывающий в файл.
FilterInputStream - Реализация InputStream
FilterOutputStream - Реализация OutputStream
InputStream - Абстрактный класс, описывающий поток ввода.
OutputStream - Абстрактный класс, описывающий поток вывода.
ObjectInputStream - Входной поток для объектов.
ObjectOutputStream - Выходной поток для объектов.
PipedInputStream - Входной канал (например, межпрограммный).
PipedOutpudStream - Выходной канал.
PrintStream - Выходной поток, включающий print() и println().
PushbackInputStream - Входной поток, поддерживающий однобайтовый возврат.
RandomAccessFile - Поддерживающий файловый ввод – вывод с произвольным доступом.
SequenceInputeStream - Входной поток, представляющий собой комбинацию двух и более входных потоков, которые читаются совместно – один после другого.

Классы символьных потоков


Основными абстрактными классами симовольного потока являются классы Reader и Writer. Эти абстрактные классы управляют потоками символов Unicode. В Java предусмотрено несколько конкретных подклассов для каждого из них. Абстрактные классы Reader и Writer определяют несколько ключевых методов, которые реализуют другие потоковые классы. Два наиболее важных – это read () и write(), которые, соответственно читают и пишут символьные данные. Эти методы переопределяются в потоковых классах – наследниках. Классы символьных потоков перечислены ниже.

Классы символьных потоков BufferedReader - Буферизованный входной символьный поток. BufferedWriter - Буферизованный выходной символьный поток. CharArrayReader - Входной поток, котрый читает из символьного массива. CharArrayWriter - Выходной поток, котрый читает из символьного массива. FilterWriter - Фильтр Писатель. FilterReader - Фильтр читатель. FileWriter - Выходной поток, пишущий в файл FileReader - Входной поток, пишущий в файл InputStreamRader - Входной поток, транслирующий байты в символы. LineNumberReader - Входной поток, подсчитывающий строки. OutputStreamWriter - Выходной поток, транслирующий байты в символы. PipedReader - Входной канал. PipedWriter - Выходной канал PrintWriter - Выходной поток, включающий print() и println(). PushbackReader - Входной поток, позволяющий возвращать символы обратно в поток. Reader - Абстрактный класс, описывающий символьный ввод. StringReader - Входной поток, читающий из строки. StringWriter - Входной поток, пишущий в строку. Writer - Абстрактный класс, описывающий символьный вывод

Чтение консольного ввода


В Java 1.0 единственным способом выполнения консольного ввода было использование байтового потока, и существует больщой объем старого кода, в котором применяется этот подход. Сегодня применение байтового потока для чтения консольного ввода попрежнему технически возможно, но поступать так не рекомендуется. Предпочтительный метод чтения консольного ввода – это использовать символ – орентированный поток, что значительно упрощает возможности интернационализации и поддержки разрабатываемых программ. В Java консольный ввод выполныется чтением System.in. Чтобы получить символьный поток, присоединенный к консоли, вы должны поместить System.in в оболочку объекта BufferedReader. BufferedReader поддерживает буфферизованный входной поток. Наиболее часто импользуемый его конструктор выглядит так:

BufferedRader(Reader inputReader)


Приведенной выше примере inputReader – это поток, который связывается с создаваемым экземпляром BufferedRader. Rader – абстрактный класс. Одним из его конскретных наследников является InputStreamReader, который преобразует байты в символы. Для получения объекта InputStreamRaeder, который присоединен к System.in можно применить следующую строку кода:

InputStreamReader()

Поскольку System.in ссылается на объект типа InputStream, он должен быть использован как параметр inputStream. Собрав все вместе, получим следующую строку кода, которая создает BufferedReader, соединенный с клавиатурой:
BufferaedReader br = new BufferedReader(new InputStreamReader(System.in));

После выполнения этого оператора br представляет собой основанный на символах поток, подключенный к консоли через System.in.

Чтение символов


Для чтения символов из BufferedReader применяется read(). Ниже показана версия read(), которая будет использоваться:

Int read() throws Ioexception

Каждый раз, когда вызывается метод read(), он читает символ из входного потока и возвращает его как целое значение. При достижении конца потока везвращается -1. Как видите, метод может возбудить исключение IOException. В следующей программе демонстрируется применение read(), читая символы с консоли до тех пор, пока не пользователь не ведет "q”. Обратите внимание, что любые исключения ввода - вывода, которые могут быть сгенирированы, просто передаются в main(). Такой подход распространен при чтении с консоли, но при жеании вы можете обработать ошибки такого рода самостоятельно.
//Использование BufferedReader для чтения символов с консоли.
//Import java.io.*;
//Class BRRead{
//Public static void main(Straing args[]) throws IOException
//{
//char c;
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//System.out.println("Вводите символы, ’q’ – для вывода.”);
//// читать символы
//do{
//c = (char) br.read();
//System.out.println(c);
//}while(c!= ‘q’);
//}
//}


Ниже показан пример запуска этой прогаммы:
Вводите симолы, ‘q’ – для вывода.
123abcq
1
2
3
A
B
C
Q
Этот вывод может выгдядеть немного не так, как вы ожидали, потому что System.in Является строчно – буферизованными по цмолчанию. Это значит, что никакого ввода действительности программе предается до тех пор, пока будет нажата клавиша (ENTER). Как можно предположить, это делает read() лишь отчасти пременимым для интерактивного консольного.

Чтение строк


Чтобы прочесть строку с клавиатуры, используйте версию метода readLine(), который является членом класса BufferedReader. Его общая форма такова:
String readLine() throws IOException
Как видите, он возвращает объект String. Следующая программа демонстрирует BuferedReader и метод readLine(). Программа читает и отображает строки текста до тех пор, пока вы не введете слово «стоп»:

Import java.io.*;


Class BRReadLines {
public static void main(String args[]) throws IOException
{
//Создатель BufferedReader с использованием System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in) );
String str;
System.out.println("Вводите строки текста.”);
System.out.println("Введите «стоп» для завершения.”);
do {
str = br.readLine();
System.out.println(str);
} while(!str.equals("стоп”));
}
}


В следующем примере создается крошечный тестовый редактор. В коде создается массив объектов String и затем читаются строки текста с сохранением каждой строки в виде элемента массива. Чтение произвидится до 100 строк или до того, как будет введено слово «стоп». Для чтения с консоли используется BuffeReader.

//Крошечный редактор.
import java.io.*;
class TinyEdit {
public static void main(String args[]) throws IOException
{
//Создатель BufferedReader, используя System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str[] = new String[100];
System.out.println("Вводите строки текста.”);
System.out.println("Введите ‘стоп’ для завершения.”);
for (int i = 0; i < 100; i++) {
str[i] = br.readLine();
if(str[i].equels("стоп”)) break;
}
System.out.println("\nВот ваш файл:”);
//отобразить строки
for(int i = 0; i<100; i++) {
if(str[i].equals("стоп”)) break;
System.out.println(str[i]);
}
}
}

Ниже показан результат запуска этой программы:


Вводите строки текста.
Введите ‘стоп’ для завершения.
Это строка один.
Это строка два.
Java делает работу со строками простой.
Просто создайте объект String.
стоп
Вот ваш файл:
Это строка один.
Это строка два.
Java делает работу со строками простой.
Просто создайте объект String.

Запись консольного вывода


Консольный вывод проще всего осуществлять с помощью методов print() и println. Эти методы определены в классе PrintSteam (котрый является типом объекта System.out). Даже несмотря на то, что System.out – байтовый поток, применение его для вывода в простых программах вполне оправдано. Тем не менее, в следующем разделе описана символ – ориентированная альтернатива. Поскольку PrintStream – выходной поток, унаследованный от OutputStream, он также реализует низкоуревневый метод write(). То есть write() может применяться для записи на консоль. Простейшая форма write(), определенного в PrintStream, показана ниже:

void write(int byteval)

Этот метод пишет в поток байт, переданных в byteval. Хотя параметр byteval объявлен как целочисленный, записываются только 8 его младших бит. Вот короткий пример, использующий write() для вывода буквы «А» с последующим преводом строки на экран:
//Демонстрация System.out.write().
class WriteDemo {
public static void main(String args[]) {
int b;
b = ‘A’;
System.out.write(b);
System.out.write(‘\n’);
}
}

Вам не часто придется использовать write() для вывода на консоль (хотя в некоторых ситуациах это и удобно), поскольку значительно проще применять для этого print() и println().

Класс PrintWriter


Хотя примение System.out для вывода на консоль допустимо, он рекомендуется в основном для целей отладки программ. PrintWriter определяет несколько конструкторов. Один из тех, которые мы будем использовать, показан ниже:

PrintWriter(OutputStream outputStream, boolean flushOnNewline)

Выше приведенном примере outputStream –является объектом типа OutputStream, а flushOnNewline управляет тем, будет ли Java сбрасывать буфер в выходной поток каждый раз при вызове метода println(). Если flushOnNewline равно true, то происходит автоматический сброс буфера, если же false, то автоматический не делается. PrintWriter поддерживает методы print() и println() для всех типов, включая object. То есть вы можете использовать эти методы таким же способом, как они применяются в System.out. Если аргумент не простого типа, то PrintWriter вызыват мотод toString и затем печатает результат. Чтобы писать на консоль с помощью PrintWriter, специфицируйте System.out в качестве выходного потока и сбрасываете поток после каждого символа новой строки.

Например

PrintWriter pw = new PrintWriter(System.out, true);

Приведенной выше примере строка кода создает PrintWriter, который подключен к консольному выводу. Показанное ниже приложение демонстрирует применение PrintWriter для управления консольным выводом:
//Демонстрация PrintWriter
import java.io.*;
public class PrintWriterDemo {
public static void main(String args[]) {
PrintWriter pw = new PrintWriter(System.out, true);
Pw.println("Это строка”);
Int i = -7;
Pw.println(i);
Double d = 4.5e – 7;
Pw.println(d);
}
}

Вывод этой программы будет выглядеть следующим оразом:

Это строка
- 7
4.5Е – 7
Помните, что нет ничего неправильного в применении System.out для простого текстового вывода на консоль. Однако PrintWriter обеспечит возможность простой интернационализации для реальных программ.


Чтение и запись файлов


Java предоставляет множество классов и методов, которые позволяют вам читать и записывать файлы. В Java все файлы байт – ориентированы, и Java предоставляет методы для чтения и записи байтов в файл. Однако Java позволяет также поместить байт ориентированные файловые потоки в оболочки символ – ориентированных объектов. Java предоставляет множество классов и методов, которые позволяет вам читать и записывать файлы. В Java все файлы байт – ориентированы, и Java предоставляет методы для чтения и записи байтов в файл. Однако Java позволяет также поместить байт – ориентированные файловые потоки в оболочки символ – ориентированных объектов. Для из наиболее часто используемых потоков класса – это FileInputStream и FileOutputStream, которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, вы просто создаете объект одного из этих классов, указав имя файла в качестве аргумента конструктора. Хотя оба класса имеют и дополнительные переопределенные конструкторы, мы будем использовать только следующие из них:

FileInputStream(String fileName) throws FileNotFoundEcxeption
FileOutputStream(String fileName) throws FileNotFoundEcxeption


Здесь filename – имя файла, которые вы хотите открыть. Когда вы создаете входной поток, то если файл не существовал, возбуждается исключение FileNotFountException. Для выходной поток, если файл не может быть создан, также возбуждается исключение FileNotFountException. Когда выходной файл открыть, любой ранее существовавший файл с тем же именем уничтожается. Когда вы завершаете работу с файлом, вы должны закрыть его вызовом метода close(). Этот метод определен и в FileInputStream и в FileOutputStream, как показано ниже:

void close() throws IOException

Чтобы читать файл, вы можете применять версию метода read(), которые определен в FileInputStream. Та, что мы будем использовать, выглядит так:

Int read() throws IOException

Всякий раз, когда вызывается этот метод, он читает единственный байт из файла и возвращает его как целое. Read() возвращает – 1, когда достигнуть конец файла. Метод может возбуждать исключение IOException.
В следующей программе read() используется для ввода и отображения содержимого текстового файла, имя которого специфицировано в аргументе командной строки. Обратите внимание на блок try/catch, обрабатывающий две ошибки, которые могут возникнуть при работе программы – когда указанный когда файл не найден, либо когда пользователь забыл указать имя файла. Вы можете применять тот же подход всякий раз при использовании аргументов командной строки. Другие возможные исключения ввода – вывода просто передаются в main(), что вполне приемлемо для такого простого примера. Однако, работа с файлами. Часто вы пожелаете обработать самостоятельно все исключение ввода – вывода.

/* Отображает текстового файла.
Чтобы использовать эту программу, укажите
имя файла, который хотите посмотреть.
Например, чтобы посмотреть файл TEST.TXT,
Используйте слудующую командную строку:
Java ShowFile TEST.TXT
*/
Import java.io.*;
class ShowFile {
public static void main(String args[])
throws IOException
{
int i;
FileInputStream fin;

try {
fin = new FileInputStream(args[0]);
} catch(FileNotFountException e) {
System.out.println("Файл не найдена”);
return;
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Использование: ShowFile Файл”);
return;
}
//читать символ до получения символа EOF (конец файла)
do {
i = fin.read(); vif(I ! = 1) System.out.print((char) i);
}while(i ! = -1);
fin.close();
}
}


Для записи в файл вы будете использовать метод write(), определенныый в FileOutputStream. Его простейшая форма выглядит так:

void write(int byteval) throws IOException

Это метод пишет в файл байт, переданный в bytevavl . Хотя byteval объявлен как целочисленный, в файл записываются только его младшие восемь бит. Если при записи произойдет ошибка, возбуждается исключение IOException. В следующем примере write() используется для копирования текстового файла:


/*Копирование текстового файла.
Для использования этой программы укажите
имена исходного и целевого файлов.
Например, чтобы скопировать файл FIRST.TXT в файл
SECOND.TXT, используйте следующую командную строку:
Java CopyFile FIRST.TXT SECOND.TXT
*/
import java.io.*;
class CopyFile {
public static void main(String args[]) throws IOExecption
{
int i;
class CopyFile {
public static void main(String args[]) throws IOException
{
int i;
FileInputStream fin;
FilePutputStream fount;
try {
//открыть входной файл
try {
fin = new FileInputStream(args [0]);
}catch(FileNotFountException e) {
System.out.println("Входной файл не найден”);
return;
}
//открыть выходной файл
try {
fout = new FileOutputStream(args [0]);
}catch(FileNotFountException e) {
System.out.println("Ошибка открытия выходного файла”);
return;
}
}catch(ArrayIndexoutOfBoundsException e) {
System.out.println("Использование: CopyFile Исходный целевой”);
return;
}
//Копировать файт
try{
do{
i = fin.read();
if(i ! = -1) fount.write(i);
}while(IOException e) {
System.out.println("Ошибка файла”);
}
fin.close();
fin.close();
}
}


Обратите внимание на способ обработка потенциальных ошибки ввода – вывда в этой программе. В отличие от некоторых других языков программирования, включая С и С++, которые используют коды ошибок для обнаружения файловых ошибок, Java применяет свой механизм исключений. Это не только делает управление файлами понятнее, но также позволяет Java просто отличать условие достижения конца файла от файловых ошибок во время ввода. В С/С++ многие функции ввода возвращают одно и то же значение, когда происходит ошибка и когда достигается конец файла. (То есть в С/С++ условие EOF часто отображается на то же значение, что и ошибка ввода.) Обычно это означает, что программист обязан включать дополнительные операторы для определения того, какое событие на самом деле произошло. В Java ошибки передаются вашей программе в виде исключений, а не через значение, возвращаемое read(). То есть, когда read() возвращает -1, это значит только одно: достигнут конец файла.
Copyright exshark © 2024
Сделать бесплатный сайт с uCoz