|
|||||||
|
Ввод – Вывод в 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() . Такой подход распространен при чтении с консоли, но при жеании вы можете обработать ошибки такого рода самостоятельно.
Ниже показан пример запуска этой прогаммы: Вводите симолы, ‘q’ – для вывода. 123abcq 1 2 3 A B C Q Этот вывод может выгдядеть немного не так, как вы ожидали, потому что System.in
Является строчно – буферизованными по цмолчанию. Это значит, что никакого ввода действительности программе предается до тех пор, пока будет нажата клавиша (ENTER).
Как можно предположить, это делает read() лишь отчасти пременимым для интерактивного консольного.
Чтение строкЧтобы прочесть строку с клавиатуры, используйте версию метода readLine() , который является членом класса BufferedReader . Его общая форма такова:
String readLine() throws IOException
Как видите, он возвращает объект String .
Следующая программа демонстрирует BuferedReader и метод readLine() . Программа читает и отображает строки текста до тех пор, пока вы не введете слово «стоп»:
В следующем примере создается крошечный тестовый редактор. В коде создается массив объектов String и затем читаются строки текста с сохранением каждой строки в виде элемента массива. Чтение произвидится до 100 строк или до того, как будет введено слово «стоп». Для чтения с консоли используется BuffeReader .
Ниже показан результат запуска этой программы: Вводите строки текста. Введите ‘стоп’ для завершения. Это строка один. Это строка два. 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() для вывода буквы «А» с последующим преводом строки на экран:
Вам не часто придется использовать write() для вывода на консоль (хотя в некоторых ситуациах это и удобно), поскольку значительно проще применять для этого print() и println() .
Класс PrintWriterХотя примение System.out для вывода на консоль допустимо, он рекомендуется в основном для целей отладки программ.
PrintWriter определяет несколько конструкторов. Один из тех, которые мы будем использовать, показан ниже:
PrintWriter(OutputStream outputStream, boolean flushOnNewline)
Выше приведенном примере outputStream –является объектом типа OutputStream, а Чтение и запись файловJava предоставляет множество классов и методов, которые позволяют вам читать и записывать файлы. В Java все файлы байт – ориентированы, и Java предоставляет методы для чтения и записи байтов в файл. Однако Java позволяет также поместить байт ориентированные файловые потоки в оболочки символ – ориентированных объектов. Java предоставляет множество классов и методов, которые позволяет вам читать и записывать файлы. В Java все файлы байт – ориентированы, и Java предоставляет методы для чтения и записи байтов в файл. Однако Java позволяет также поместить байт – ориентированные файловые потоки в оболочки символ – ориентированных объектов. Для из наиболее часто используемых потоков класса – это FileInputStream и FileOutputStream , которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, вы просто создаете объект одного из этих классов, указав имя файла в качестве аргумента конструктора. Хотя оба класса имеют и дополнительные переопределенные конструкторы, мы будем использовать только следующие из них:
FileInputStream(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() , что вполне приемлемо для такого простого примера.
Однако, работа с файлами. Часто вы пожелаете обработать самостоятельно все исключение ввода – вывода.
/* Отображает текстового файла.
Для записи в файл вы будете использовать метод write() , определенныый в FileOutputStream . Его простейшая форма выглядит так:
void write(int byteval) throws IOException
Это метод пишет в файл байт, переданный в bytevavl . Хотя byteval объявлен как целочисленный, в файл записываются только его младшие восемь бит. Если при записи произойдет ошибка, возбуждается исключение IOException . В следующем примере write() используется для копирования текстового файла:
Обратите внимание на способ обработка потенциальных ошибки ввода – вывда в этой программе. В отличие от некоторых других языков программирования, включая С и С++, которые используют коды ошибок для обнаружения файловых ошибок, Java применяет свой механизм исключений. Это не только делает управление файлами понятнее, но также позволяет Java просто отличать условие достижения конца файла от файловых ошибок во время ввода. В С/С++ многие функции ввода возвращают одно и то же значение, когда происходит ошибка и когда достигается конец файла. (То есть в С/С++ условие EOF часто отображается на то же значение, что и ошибка ввода.) Обычно это означает, что программист обязан включать дополнительные операторы для определения того, какое событие на самом деле произошло. В Java ошибки передаются вашей программе в виде исключений, а не через значение, возвращаемое read() . То есть, когда read() возвращает -1, это значит только одно: достигнут конец файла.
|
Copyright exshark © 2024 |