Входно-изходните операции служат за комуникация с конзолата (клавиатура+видеомонитор), с файлове и/или в мрежа



Дата27.09.2016
Размер78.07 Kb.
#10743
Вход/Изход

Входно-изходните операции служат за комуникация с конзолата (клавиатура+видеомонитор), с файлове и/или в мрежа.

Потокът е абстракция, която или създава, или получава информация. Прието е входно/изходните данни да се възприемат като потоци. И двата вида потоци не са свързани с конкретни типове периферни устройства. Java реализира потоците в йерархии от класове, дефинирани в пакета java.io

Байтовите потоци осигуряват удобен начин за обслужване на вход и изход от байтове. Те се използват за четене и запис на двоични данни. Особено са полезни при работа с файлове.

Символните са предназначени да обслужват вход и изход от символи. Те използват Unicode и затова могат да се иnтернационализират. В някои случаи символните потоци са по-ефективни от байтовите.

На най-ниско ниво целият вход/изход е байтово ориентиран. Базираните на символи потоци просто осигуряват удобен и ефективен начин за обработка на символи.



1. Байтови потоци

За работата с потоци са дефинирани класове. Почти всички са извлечени от двата абстрактни класа, наричани InputStream и OutputStream.

Всички класове, извлечени от InputStream, се наследяват от него и припокриват абстрактния метод read(), предназначен за четене на единичен байт или на масив от байтове. Аналогично за OutputStream и write().

Обикновено методите InputStream и OutputStream могат да генерират изключение от тип IOException.
1.1. Предварително дефинирани потоци

java.lang

System

in е обект от тип InputStream

out - е обект от тип PrintStream (наследник на OutputStream)

err- е обект от тип PrintStream

Тъй като в Java всичко е обекти, за осъществяванена входно/изходните операции се създават и използват обекти-потоци. За реализация на една операция обикновено се използват повече обекти, които се влагат един в друг.

При четенето на данни се използва следния подход: отначало се създава обект на определен входен поток и след това се указва източника на данните. Данните се четат под формата на байтове. При запис на данни в поток се използва следният основен подход: отначало се създава обект на определен изходен поток и след това се указва къде да бъдат записани данните. Последните се записват под формата на байтове. Много често даден поток се явява входен за друг и т.н.
1.2. Четене на вход от конзолата

За комерсиален код предпочитаният метод за четене на вход е да използвате символно-ориентирания поток. Това прави профграмата по-лесна за интернационализиране и по-лесна за поддръжка. Също така е по-удобно да работите директно със символи, вместо да преобразувате от байтове в символи и обратно.



Версии на метод read()

int read ( ) throws IOException

int read ( byte data[]) throws IOException

int read (byte data[], int start, int max ) throws IOException

read() връща –1, когато се достигне край на потока

Втората версия чете байтове от входния поток и ги поставя в data, докато се напълни масива, докато се достигне края на потока или възникне грешка Връща броя на прочетените байтове или -1

Третата версия чете входа в data, започвайки от мястото, указано от старт. Запазват се до max на брой байтове. Той връща броя на прочетените байтове или-1, когато се достигне края на потока. Всички генерират изключение от тип IOException, когато възникне грешка. При четенето на System.in натискането на ENTER генерира условие за край на потока.


Зад. 1

Въведете от клавиатурата текст, като използвате метод read(byte b[])



import java.io.* ;
class ReadByte {

public static void main (String args[]) throws IOException {

byte data []= new byte[100];

System.out.println("Enter smth");

System.in.read(data);

System.out.print("your entered: ");

for (int i=0; i

System.out.print( (char) data[i]);

}

}


зад 2

Въведете от клавиатурата символ и го отпечатайте . Използвайте метод read()






зад 3

Въведете от клавиатурата текст и запишете първите к символа от него в масив от байтове го отпечатайте .







1.3. Записване на изход в конзолата

метод write( ) от PrintStream

void write (int byteval) throws IOException

въпреки, че byteval е декларирана као цяло число, само младшите 8 бита се записват.

По-удобно е да се използва print вместо write


зад 4

Да се реализира задача 3 чрез метод write() вместо print() за отпечатване на масива data2


1.4. Четене и запис на файлове чрез байтови потоци

1.4.1. Вход от файл

Един файл се отваря за вход чрез създаване на обект от тип FileInputStream

Най-често използван конструктор



FileInputStream (String fileName) throws FileNotFoundException

Изключението се генерира, ако файлът не съществува

За четене от файл се използва метода read( )

int read( ) throws IOException

При всяко свое извикване read( ) прочита един байт от файла и го връща като целочислена стойност. Връща –1 при достигане на края на файла.

Затваряне на файла



void close( ) throws IOException

зад 5


Следващата програма прочита байтове от файл с посочено име, зададено като параметър на програмата и извежда съдържанието му на екрана.


import java.io.* ;

class ShowFile {

public static void main (String args[]) throws IOException {

int i;


FileInputStream fin;

try {


fin = new FileInputStream(args[0]);

}

catch (FileNotFoundException exc) {



System.out.println(“File not found”);

return;


}

catch (ArrayIndexOutOfBoundsException exc) {

System.out.println(“Usage: Showfile File”);

return;


}

// чете байтове, докато не срещне EOF

do {

i = fin.read();



if (i != -1) System.out.print((char) i);

}

while (i != -1);



fin.close();

}

}



1.4.2. Запис във файл

Създава се обект от тип FileOutputStream. Използват се следните му конструктори:

FileOutputStream (String fileName) throws FileNotFoundException

FileOutputStream (String fileName, boolean append) throws FileNotFoundException



При първия конструктор, ако вече има такъв файл, то той се унищожава. При втория конструктор, ако стойността на append е true, добавяме към вече записаното в него. В противен случай файлът се презаписва.
За записване на файл се използва метода write( )

void write(int byteval) throws IOException


Преди да се запише действително във файла, изходът се буферира, докато не се достигне определен размер с данни, който да се запише наведнъж. Ако искате да запишете данните, независимо дали буферът се е напълнил или не можете да използвате flush( )

void flush ( ) throws IOException


За затваряне на метода се използва метода close ( )

void close( ) throws IOException

Затварянето на файла освобождава заделените за него системни ресурси и дава възможност те да се използват за друг файл. Това също така гарантира, че изходът, останал в дисковия буфер, в действителност се записва на диска.
зад 6

Да се копира съдържанието на един текстов файл в друг







1.4.3. Четене и запис на двоични данни

Дотук записвахме байтове, съдържащи ASCII символи, но се налага четене и запис на други типове. За четене и запис на двоични стойности от простите типове на Java се използва DataInputStream и DataOutputStream.

DataOutputStream реализира интерфейса DataOutput. Тези данни(всички прости типове) се записват чрез използването на вътрешния им двоичен формат. Най-често използваните изходни методи са табл.10-5
Конструктор на DataOutputStream

DataOutputStream(OutputStream outputStream)


OutputStream e потокът, в който се записват данните. За да запишете изхода във файл, можете да използвате обекта, създаден от FileOutputStream за този параметър.
Аналогично за DataInputStream Конструктор:

DataInputStream(InputStream inputStream)

Зад. 7


Да се запишат и прочетат стойности от тип int, double и boolean във двоичен файл.
1.6. И зползване на базираните на символи потоци в Java
1.6.1. Вход от конзолата

Най-отгоре в йерархията от символни потоци се намират абстрактните класове Reader и Writer. Всички методи могат да генерират изключение от тип IOException.

За код, който ще се интернационализира, въвеждането о тконзолата чрез използване на базираните на символи потоци е по-добър и удобен начин за четене на символи от клавиатурата, отколкото използването на байтови потоци. Тъй като обаче System.in е байтов поток ще трябва да опаковате System.in в някой тип на Reader.

Най-добрият клас за четене на вход от конзолата е BufferedReader, който поддържа буфериран входен поток. Не можете да конструирате BufferedReader директно от System.in Вместо това трябва най-напред да го конвертирате в символен поток. За да направите това ще използвате класа InputStreamReader, който преобразува байтове в символи. За да получите обект от тип InputStreamReader, свързан със System.in, използвайте конструктора:

InputStreamReader(InputStream inputStream)

Тъй като System.in се отнася за обект от тип InputStream, той може да се използва за аргумент на InputStreamReader.

След това, като използвате създадения от InputStreamReader обект, конструирайте обект от тип BufferedReader чрез конструктора

BufferedReader (Reader inputReader)

InputReader е потокът, който свързва със създаваната инстанция на BufferedReader

Горното може да бъде записано и така



BufferedReader br = new BufferedReader(new InputStreamReader(System.in))



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

Четене на стрингове

За прочитане на низ от клавиатурата използвайте версията на readLine ( ), която е член на класа BufferedReader

String readLine( ) throws IOException

Методът връща обект от тип String, съдържащ прочетените символи. Той връща null, ако бъде направен опит за четене в края на потока.

// Програмата чете и показва редове с текст, докато не въведете stop

class ReadLines {

public static void main (String args [ ] ) throws IOException {

{

BufferedReader bufr = new BufferedReader(new InputStreamReader (System.in));



String str;

System.out.println(“Enter lines of text.”);

System.out.println(“Enter ‘stop’ to quit.”);

do {


str = bufr.readLine( );

System.out.println(str);

}

while (!str.equals(“stop”));



}

}



1.6.2. Извеждане на конзолата

За истинските програми предпочитаният метод за запис в конзола е чрез използване на PrintWriter поток. Конструктор

PrintWriter (OutputStream outputStream, boolean flushOnNewline)


Поддържа методите print( ) и println( )

Ако параметърът на е от прост тип, методите на PrintWriter ще извикат метода toString() на обекта, и след това ще отпечатат резултата.
Пример за извеждане

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


FileWriter'>1.6.3. Файлов В/И

FileWriter конструктори

FileWriter (Sring fileName) throws IOException

FileWriter (Sring fileName, boolean append) throws IOException



FileWriter наследява OutputStreamWriter и Writer.

FileReader (Sring fileName) throws FileNotFoundException


1.7. Използване на типовите обвивки за преобразуване на низове от числа

Методът printdln( ) осигурява удобен начин за извеждане на различни типове данни към конзолата, включително и числови стойности от вградени типове, като int, double… По този начин printdln( ) автоматично преобразува числовите стойности в тяхната текстова форма. Java обаче не осигурява входен метод, който да чете и преобразува низове, съдържащи числови стойности, в техния вътрешен двоичен формат. За да се изпълни това се използват типовите обвивки (type wrappers)







Сподели с приятели:




©obuch.info 2024
отнасят до администрацията

    Начална страница