ОСНОВЫ ВВОДА/ВЫВОДА

Содержание

Слайд 2

Основы ввода/вывода Реальные приложения Java не основаны на консольных текстовых программах.

Основы ввода/вывода

Реальные приложения Java не основаны на консольных текстовых программах.
Они

являются графическими апплетами, которые для взаимодействия с пользователем полагаются на систему классов AWT (Abstract Window Toolkit, инструментарий абстрактного окна) языка Java.
Поддержка Java для консольного ввода/вывода ограничена и не очень удобна в использовании — даже в простых примерах программ.
Текстовый консольный ввод/вывод в действительности не очень важен для Java-программирования.
Несмотря на это, Java обеспечивает сильную, гибкую поддержку по существу текстового ввода/вывода для файлов и сетей. Система ввода/вывода Java связна и непротиворечива.
Слайд 3

Потоки Java-программы выполняют ввод/вывод через потоки. Поток является абстракцией, которая или

Потоки

Java-программы выполняют ввод/вывод через потоки.
Поток является абстракцией, которая или производит,

или потребляет информацию.
Поток связывается с физическим устройством с помощью системы ввода/вывода Java (Java I/O system).
Все потоки ведут себя одинаковым образом, хотя фактические физические устройства, с которыми они связаны, могут сильно различаться.
Таким образом, одни и те же классы и методы ввода/вывода можно применять к устройствам любого типа.
Поток ввода может извлекать много различных видов входных данных: из дискового файла, с клавиатуры или сетевого разъема.
Поток вывода может обратиться к консоли, дисковому файлу или сетевому соединению (сокету).
Благодаря потокам ваша программа выполняет ввод/вывод, не понимая различий между клавиатурой и сетью.
Java реализует потоки с помощью иерархии классов, определенных в пакете java.io.
Слайд 4

Байтовые и символьные потоки Java 2 определяет два типа потоков (точнее

Байтовые и символьные потоки

Java 2 определяет два типа потоков (точнее —

поточных классов и объектов): байтовый и символьный.
Байтовые потоки предоставляют удобные средства для обработки ввода и вывода байтов. Байтовые потоки используются, например, при чтении или записи данных в двоичном коде.
Символьные потоки предоставляют удобные средства для обработки ввода и вывода символов. Они используют Unicode и поэтому могут быть интернационализированы. Кроме того, в некоторых случаях символьные потоки более эффективны, чем байтовые.
На самом низком уровне весь ввод/вывод все еще байтовый. Символьно-ориентированные потоки обеспечивают удобные и эффективные средства для обработки символов.
Слайд 5

Классы байтовых потоков Байтовые потоки определяются в двух иерархиях классов. Наверху

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

Байтовые потоки определяются в двух иерархиях классов.
Наверху этой

иерархии — два абстрактных класса: Inputstream и Outputstream.
Каждый из этих абстрактных классов имеет несколько конкретных подклассов, которые обрабатывают различия между разными устройствами, такими как дисковые файлы, сетевые соединения и даже буферы памяти.
Абстрактные классы Inputstream и Outputstream определяют несколько ключевых методов, которые реализуются другими поточными классами. Два наиболее важных— read() и write(), которые, соответственно, читают и записывают байты данных.
Оба метода объявлены как абстрактные внутри классов inputstream и outputstream и переопределяются производными поточными классами.
Слайд 6

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

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

Слайд 7

Классы символьных потоков Символьные потоки определены в двух иерархиях классов. Наверху

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

Символьные потоки определены в двух иерархиях классов. Наверху этой

иерархии два абстрактных класса: Reader и Writer.
Они обрабатывают потоки символов Unicode.
Абстрактные классы Reader и Writer определяют несколько ключевых методов, которые реализуются другими поточными классами.
Два самых важных метода — read() и write(), которые читают и записывают символы данных, соответственно.
Они переопределяются производными поточными классами.
Слайд 8

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

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

Слайд 9

Предопределенные потоки Все программы Java автоматически импортируют пакет java.lang. Этот пакет

Предопределенные потоки

Все программы Java автоматически импортируют пакет java.lang.
Этот пакет определяет

класс с именем system, инкапсулирующий некоторые аспекты исполнительной среды Java.
Класс system содержит также три предопределенные поточные переменные in, out и err. Эти поля объявлены в System со спецификаторами public и static.
Объект System.out называют потоком стандартного вывода. По умолчанию с ним связана консоль.
На объект System.in ссылаются как на стандартный ввод, который по умолчанию связан с клавиатурой.
К объекту System.err обращаются как к стандартному потоку ошибок, который по умолчанию также связан с консолью.
Однако эти потоки могут быть переназначены на любое совместимое устройство ввода/вывода.
Слайд 10

Чтение консольного ввода Консольный ввод в Java выполняется с помощью считывания

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

Консольный ввод в Java выполняется с помощью считывания из

объекта System.in.
Чтобы получить символьный поток, который присоединен к консоли, вы переносите ("упаковываете") System.in в объект типа BufferedReader.
Класс BufferedReader поддерживает буферизированный входной поток. Обычно используется следующий его конструктор:
BufferedReader(Reader inputReader)
где inputReader — поток, который связан с создающимся экземпляром класса BufferedReader.
Reader — абстрактный класс. Один из его конкретных подклассов — это InputStreamReader, который преобразовывает байты в символы.
Чтобы получить InputStreamReader-объект, который связан с System.in, используйте следующий конструктор:
InputstreamReader(InputStream inputstream)
Поскольку System.in ссылается на объект типа inputstream, его можно использовать в качестве параметра inputstream.
Следующая строка кода создает объект класса BufferedReader, который связан с клавиатурой:
BufferedReader br = new BufferedReader(new InputstreamReader(System.in));
После того как этот оператор выполнится, объектная переменная br станет символьным потоком, связанным с консолью через System.in.
Слайд 11

Чтение символов Для чтения символа из BufferedReader используйте метод read(). Версия

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

Для чтения символа из BufferedReader используйте метод read(). Версия read(),

которую мы будем применять, такова:
int read() throws IOException
При каждом вызове read() читает символ из входного потока и возвращает его в виде целочисленного значения. Когда read о сталкивается с концом потока, то возвращает -1. Как вы видите, он может выбрасывать исключение ввода/вывода (I/O-исключение — IOException).
Слайд 12

Чтение символов // Использует BufferedReader для чтения символов с консоли, import

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

// Использует BufferedReader для чтения символов с консоли,
import java.io.*;
class

BRRead
{
public static void main(String args [ ])
throws IOException
{
char c;
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
System.out.println("Введите символы, 'q' - для завершения.");
// чтение символов
do
{
с = (char) br.read();
System.out.println(с);
}
while(c != 'q');
}
}
Слайд 13

Чтение строк Для чтения строки, вводимой с клавиатуры, используйте версию метода

Чтение строк

Для чтения строки, вводимой с клавиатуры, используйте версию метода readLine(),

который является элементом класса BufferedReader. Его обшая форма:
String readLine() throws IOException
Как видно, он возвращает string-объект.
Слайд 14

Чтение строк // Крошечный редактор. import java.io..*; class TinyEdit { public

Чтение строк

// Крошечный редактор.
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("Введите 'stop' для завершения.");
for (int i=0; i<100; i++)
{
str[i] = br.readLine();
if(str[i].equals("stop"))
break; }
System.out.println(“\n Вот ваш файл:");
// Вывести строки на экран.
for (int i=0; i<100; i++) {
if(str[i].equals("stop")) break;
System.out.println(str[i]); }
} }
Слайд 15

Запись консольного вывода Консольный вывод легче всего выполнить с помощью методов

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

Консольный вывод легче всего выполнить с помощью методов print

() и println().
Эти методы определены классом Printstream (который является типом (классом) объекта System.out).
Поскольку PrintStream — выходной поток, производный от OutputStream, онтакже реализует метод нижнего уровня write().
Самая простая форма write (), определенная в Printstream, имеет вид:
void write (int byteval) throws lOException
Этот метод записывает в файл байт, указанный в параметре byteval. Хотя byteval объявлен как целое число, записываются только младшие восемь битов.
Слайд 16

Запись консольного вывода // Демонстрирует System.out.write. class WriteDemo { public static

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

// Демонстрирует 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() намного легче.
Слайд 17

Класс PrintWriter Хотя использование объекта System.out для записи на консоль все

Класс PrintWriter

Хотя использование объекта System.out для записи на консоль все еще

допустимо в Java, его применение рекомендуется главным образом для отладочных целей или для демонстрационных программ, типа тех, которые показаны в этой книге.
Для реальных Java-программ для записи на консоль рекомендуется работать с потоком типа PrintWriter.
PrintWriter — это один из классов символьного ввода/вывода. Использование подобного класса для консольного вывода облегчает интернационализацию вашей программы.
PrintWriter определяет несколько конструкторов. Мы будем использовать следующий:
PrintWriter (OutputStream OutputStream, boolean flushOnNewline)
Здесь OutputStream — объект типа OutputStream; flushOnNewline — булевский параметр, используемый как средство управления сбрасыванием выходного потока в буфер вывода (на диск) каждый раз, когда выводится символ newline (\n). Если fiushOnNewilne — true, поток сбрасывается автоматически, если — false, то не автоматически.
Printwriter поддерживает методы print () и println() для всех типов, включая Object.
Чтобы записывать на консоль, используя класс Printwriter, создайте объект System.out для выходного потока, и сбрасывайте поток после каждого символа newline.
Например, следующая строка кода создает объект типа Printwriter, который соединен с консольным выводом:
PrintWriter pw = new Printwriter(System.out, true);
Слайд 18

Класс PrintWriter // Демонстрирует Printwriter. import java.io.*; public class PrintWriterDemo {

Класс PrintWriter

// Демонстрирует Printwriter.
import java.io.*;
public class PrintWriterDemo
{
public static void

main(String args[j])
{
Printwriter pw = new Printwriter(System.out, true);
pw.printIn("Это строка:");
int i = -7;
pw.println(i);
double d = 4.5e-7;
pw.println(d);
}
Вывод этой программы:
Это строка:
-7
4.5Е-7
Слайд 19

Чтение и запись файлов Java обеспечивает ряд классов и методов, которые

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

Java обеспечивает ряд классов и методов, которые позволяют

читать и записывать файлы.
Для Java все файлы имеют байтовую структуру, a Java обеспечивает методы для чтения и записи байтов в файл.
Java позволяет упаковывать байтовый файловый поток в символьно-ориентированный объект. (Об этом позже).
Для создания байтовых потоков, связанных с файлами, чаше всего используются два поточных класса — FilelnputStream и FileOutputStream.
FilelnputStream (String fileName) throws FileNotFoundException
FileOutputStream (String fileName) throws FileNotFoundException
где fileName определяет имя файла, который вы хотите открыть.
Когда вы создаете входной поток при отсутствующем файле, выбрасывается исключение FileNotFoundException.
Для выходных потоков, если файл не может быть создан, выбрасывается такое же исключение (FileNotFoundException).
Когда выходной файл открывается, любой файл, существовавший ранее с тем же самым именем, разрушается.
Слайд 20

Чтение и запись файлов После завершения работы с файлом, его нужно

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

После завершения работы с файлом, его нужно закрыть,

вызвав метод close(). Он определен как В FilelnputStream, так и в FileOutputStream в следующей форме:
void close() throws IOException
Для чтения файла можно использовать версию метода read (), который определен в FilelnputStream.
int read() throws IOException
При каждом вызове он (метод) читает один байт из файла и возвращает его в форме целочисленного значения. Когда read о встречает символ конца файла (EOF), то возвращает -1.
Слайд 21

Чтение и запись файлов /* Выведет на экран текстовый файл. При

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

/* Выведет на экран текстовый файл.
При запуске программы

укажите (в параметре команды запуска) имя файла, который вы хотите просмотреть. Например, чтобы просмотреть файл с именем TEST.TXT, Используйте следующую командную строку
Java ShowFile TEST.TXT */
import j ava.io.*;
class ShowFile
{
public static void main(String args[])
throws IOException {
int i ;
FilelnputStream fin;
try
{
fin = new FilelnputStream(args[0]);
}

catch(FileNotFoundException e)
{
System.out.println("Файл не найден");
return;
}
catch(ArraylndexOutOfBoundsException e)
{
System.out.println("Используйте: ShowFile имя_файла");
return;
}
// читать символы файла, пока
// не встретится символ EOF
Do
{
i = fin.read();
if(I != -1) System.out.print((char) i);
}
while (i != -1) ;
in.close ();
}
}

Слайд 22

Апплеты Все предшествующие примеры в этой книге были Java-приложениями. Однако приложение

Апплеты

Все предшествующие примеры в этой книге были Java-приложениями.
Однако приложение —

это только один тип Java-программ.
Другой тип программ представлен апплетом – небольших приложений, которые доступны на Internet-сервере, транспортируются по Internet, автоматически устанавливаются и выполняются как часть Web-документа.
После того, как апплет прибывает к клиенту, он имеет ограниченный доступ к ресурсам системы, которые использует для создания произвольного мультимедийного интерфейса пользователя и выполнения комплексных вычислений без риска заражения вирусами или нарушения целостности данных.
Апплеты отличаются от приложений в нескольких ключевых областях.
Слайд 23

Апплеты import java. awt. *; Import java.applet.*; public class SimpleApplet extends

Апплеты

import java. awt. *;
Import java.applet.*;
public class SimpleApplet extends Applet
{
public void

paint(Graphics g) {
g.drawstring ("A 'Simple Applet", 20, 20);
}
}

Апплет начинается; с двух операторов import.
Первый импортирует AWT (Abstract Windowing Toolkit) - абстрактный оконный интерфейс классы.
Следующая строка в программе объявляет класс SimpleApplet. Он должен быть объявлен как public, потому что к нему необходимо обеспечить доступ из кодов, которые находятся вне программы.
Внутри SimpleApplet объявлен метод paint(). Этот метод определен в AWT и должен быть переопределен апплетом. Метод paint о вызывается каждый раз, когда апплет должен восстанавливать изображение своего вывода.
Метод paint() вызывается также, когда апплет начинает выполнение.
Метод имеет один параметр типа Graphics, через который получает графический контекст, описывающий графическую среду выполнения апплета.
Внутри paint() находится обращение к методу drawstring (), который является членом класса Graphics. Этот метод выводит строку, начиная, с указанных его аргументами (х, у)-координат в окне апплета. Он имеет следующую общую форму:
void drawstring (String massage, int x, int y)

Слайд 24

Апплеты Существует два способа выполнения апплета: Выполнение апплета Java-совместимом Web-браузером, типа

Апплеты

Существует два способа выполнения апплета:
Выполнение апплета Java-совместимом Web-браузером, типа Netscape Navigator

или Microsoft Internet Explorer.
Использование программы просмотра апплетов, типа стандартной утилиты JDK appletviewer. Программа просмотра апплетов выполняет апплет в его окне.
Для выполнения апплета в Web-браузере нужно записать короткий текстовый файл в формате языка HTML, который содержит специальный тег . HTML-файл, который выполняет simpieApplet, совсем прост:

Внутри тега его параметры width и height определяют размеры окна апплета. После создания файла, вы можете запустить свой браузер и затем загрузить этот файл, что приведет к выполнению SimpleApplet.
Слайд 25

Апплеты Несколько ключевых моментов. Апплеты не нуждаются в методе main(). Апплеты

Апплеты

Несколько ключевых моментов.
Апплеты не нуждаются в методе main().
Апплеты должны выполняться

программой просмотра апплетов или браузером, поддерживающим Java.
Пользовательский ввод/вывод в апплетах не выполняется с помощью Java-классов поточного ввода/вывода. Вместо этого апплеты используют интерфейс, обеспеченный системой AWT.
Слайд 26

Модификаторы transient и volatile Когда экземплярная переменная объявлена как transient, то

Модификаторы transient и volatile

Когда экземплярная переменная объявлена как transient, то ее

значение не будет запомнено при сохранении объекта. Например:
class T {
transient int a; // не будет сохраняться
int b; // будет сохраняться
}
Модификатор volatile сообщает компилятору, что переменная, модифицированная с его помощью, может быть неожиданно изменена другими частями вашей программы.
Слайд 27

Использование instanceof Иногда полезно распознавать тип объекта во время выполнения. Например,

Использование instanceof

Иногда полезно распознавать тип объекта во время выполнения.
Например, можно

иметь один поток выполнения для генерации различных типов объектов, а другой — для их обработки. В этой ситуации обрабатывающему процессу полезно было бы знать тип каждого объекта, принимаемого на обработку.
В Java недопустимое приведение вызывает ошибку времени выполнения. Много недопустимых приведений можно перехватить во время компиляции. Однако операции приведения, связанные с типами объектов (т. е. с иерархиями классов), могут оказаться недопустимыми и могут быть обнаружены только во время выполнения.
Операция instanceof имеет следующую общую форму:
object instanceof type
где object — экземпляр класса; type — класс (как тип). Если object-операнд имеет тип или его тип может быть приведен к типу, указанный в type-операнде, то результат операции instanceof имеет значение true. Иначе, ее результат — false. Таким образом, instanceof — это средство, с помощью которого ваша программа может получить информацию о типе объекта во время выполнения.
Операция instanceof не нужна для большинства программ, потому что, вообще-то, вы знаете тип объекта, с которым работаете.
Слайд 28

Native-методы Иногда может возникнуть желание вызвать подпрограмму, которая написана на другом

Native-методы

Иногда может возникнуть желание вызвать подпрограмму, которая написана на другом языке,

а не на Java.
Как правило, такая подпрограмма существует как выполняемый код для CPU и среды, в которой вы работаете — то есть как "родной" (native) код.
Однако из-за того, что Java-программы компилируются в байт-код, который затем интерпретируется (или компилируется "на лету") исполнительной системой Java, казалось бы, невозможно вызвать подпрограмму native-кода изнутри Java-программы.
В Java существует ключевое слово native, которое используется для объявления методов native-кода. После объявления эти методы можно вызывать внутри Java-программы точно так же, как вызывается любой другой метод Java.
Для объявления native-метода нужно предварить его заголовок модификатором native, при этом, однако, не следует определять никакого тела. Например:
public native int meth();
После объявления native-метода, следует записать сам родной метод и выполнить довольно сложную процедуру для связи его с кодом Java.
Большинство родных методов записываются на С. Механизм, используемый для интеграции С-кода с Java-программой, называется JNI (Java Native Interface — native-интерфейс Java).
Слайд 29

Native-методы // Простой пример, который //использует native-метод, public class NativeDemo {

Native-методы

// Простой пример, который
//использует native-метод,
public class NativeDemo {
int i;
public

static void main(String args[])
{ NativeDemo ob = new NativeDemo();
ob.i = 10;
System.out.println("Этот ob.i перед native-методом:" + ob.i);
ob.testO;// вызов native-метода
System.out.println("Этот ob.i после native-метода:" + ob.i); }
// объявить native-метод public native
void test ();
// загрузить DLL, который содержит static-метод
static {
System.loadLibrary("NativeDemo"); } }

Заметим, что метод test () объявлен как native и не имеет тела. Он будет реализован на С.
Обратите также внимание на блок static. Как объяснялось ранее, static-блок выполняется только один раз, когда программа начинает выполняться (или, более точно, когда его класс впервые загружается).
В данном случае он используется для загрузки DLL(Dynamic Link Library)-библиотеки, которая содержит native-реализацию метода test ().
Библиотека загружается методом loadLibrary (), который является частью класса system. Вот его общая форма:
static void loadLibrary(String filename)
Здесь filename — строка, которая специфицирует имя файла, содержащего библиотеку.

Слайд 30

Проблемы native-методов Потенциальный риск безопасности. Поскольку native-метод выполняет фактический машинный код,

Проблемы native-методов

Потенциальный риск безопасности. Поскольку native-метод выполняет фактический машинный код, он

может получать доступ к любой части хост-системы. То есть native-код не ограничен средой выполнения Java. Это может привести к заражению вирусом, например. По этой же при чине native-методы не могут использовать апплеты. Загрузка DLL-файлов может быть ограничена и подчинена одобрению руководителя службы безопасности.
Потеря мобильности. Поскольку native-код содержится в DLL-файле, он должен присутствовать на машине, выполняющей программу Java. Далее, так как любой native-метод зависит от CPU и операционной системы, каждый такой DLL-файл неизбежно непереносим. Таким образом, приложение Java, которое использует native-методы, будет способно выполниться только на машине, где был установлен соответствующий DLL-файл.