Кожна програма повинна записувати свої дані в місце зберігання або канал, і кожна програма повинна зчитувати дані з каналу або місця зберігання. У Java, ці канали, куди програми записують і звідки програми зчитують дані, називаються Потоками (Stream).
Кожен потік запису даних, містить набір методів запису. І кожен потік зчитування даних, відповідно має подібний набір методів читання. Як тільки потік створюється, всі ці методи повинні бути викликані.
Потік пов'язаний з фізичним пристроєм за допомогою системи вв/вив java. Всі потоки поводяться однаково, навіть незважаючи на те, що реальні фізичні пристрої, до яких вони підключені, відрізняються один від одного. Таким чином, одні й ті ж класи і методи вв/вив застосовні до пристроїв різного типу. Це означає, що абстракція вхідного потоку може охопити різні типи введення: з дискового файлу, клавіатури або мережного сокета (Сокети (англ. socket - заглиблення, гніздо, роз'єм) — назва програмного інтерфейсу для забезпечення обміну даними між процесами. Процеси при такому обміні можуть виконуватися як на одній ЕОМ, так і на різних ЕОМ, пов'язаних між собою мережею. Сокет - абстрактний об'єкт, що представляє кінцеву точку з'єднання).
Аналоrічно вихідний потік може посилатися на консоль, дисковий файл або підключення до мережі. Потоки - це зрозумілий спосіб поводження з вв/вив без необхідності для вашоrо коду розбиратися з різницею, наприклад, між клавіатурою і мережею. Jаvа реалізує потоки всередині ієрархії класів, визначених в пакеті java.io. Для використання класів потоків необхідно імпортувати пакет java.io.
Потік пов'язаний з фізичним пристроєм за допомогою системи вв/вив java. Всі потоки поводяться однаково, навіть незважаючи на те, що реальні фізичні пристрої, до яких вони підключені, відрізняються один від одного. Таким чином, одні й ті ж класи і методи вв/вив застосовні до пристроїв різного типу. Це означає, що абстракція вхідного потоку може охопити різні типи введення: з дискового файлу, клавіатури або мережного сокета (Сокети (англ. socket - заглиблення, гніздо, роз'єм) — назва програмного інтерфейсу для забезпечення обміну даними між процесами. Процеси при такому обміні можуть виконуватися як на одній ЕОМ, так і на різних ЕОМ, пов'язаних між собою мережею. Сокет - абстрактний об'єкт, що представляє кінцеву точку з'єднання).
Аналоrічно вихідний потік може посилатися на консоль, дисковий файл або підключення до мережі. Потоки - це зрозумілий спосіб поводження з вв/вив без необхідності для вашоrо коду розбиратися з різницею, наприклад, між клавіатурою і мережею. Jаvа реалізує потоки всередині ієрархії класів, визначених в пакеті java.io. Для використання класів потоків необхідно імпортувати пакет java.io.
В Java визначені два типи потоків (Stream): Байтовий та Символьний.
Stream |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Байтовий потік |
Символьний потік |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Байтові потоки представляють зручні засоби для управління введенням і виведенням байтів. Використовуються, наприклад, при читанні і записі бінарних даних. Символьні потоки пропонують зручні можливості управління введенням і виведенням символів. Вони використовують кодування Unicode і, таким чином, можуть бути інтернаціоналізовані. Крім того, в деяких випадках символьні потоки більш ефективні, ніж байтові. Вихідна версія java (java 1.0) не включала символьних потоків, і тому весь вв/вив був байт-орієнтованим. Символьні потоки були додані в java 1.1, і при цьому деякі байт-орієнтовані класи і методи застаріли. Ось чому старий код, до якого не використовувалися символьні потоки, повинен бути, де можливо, оновлений, щоб скористатися їх перевагами.
!!! На найнижчому рівні весь вв/вив, як і раніше, байт-орієнтований. Символьні потоки просто пропонують зручні та ефективні засоби управління символами.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ієрархія класів байтових потоків починається з двох абстрактних класів InputStream та OutputStream. В цих класах визначені методи read() та write(). | Ієрархія класів символьних потоків починається з двох абстрактних класів Reader та Writer. В цих класах визначені методи read() та write(). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Клас System
Частина можливостей вводу-виводу може бути реалізована через клас System. Клас System містить три поточних змінних: in, out та err. Це public static поля класу, які є поточними змінними.
System.out – потік стандартного виводу. За умовчанням пов'язаний з консоллю. Об'єкт типу PrintStream.
System.in – потік стандартного вводу. За умовчанням пов'язаний з клавіатурою. Об'єкт типу InputStream.
System.err – cстандартний потік помилок. За умовчанням пов'язаний з консоллю. Об'єкт типу PrintStream.
Консольний ввід
Консольний ввід в Java реалізується через зчитування з об'єкту System.in. При цьому використовується клас BufferedReader – клас буферизованого вхідного потоку (підключення пакету import java.io.*;).
Конструктор: BufferedReader(Reader)
Reader – абстрактний клас, підкласом якого є InputSrtreamReader (перетворює байти в символи)
Конструктор: InputStreamReader(InputStream)
Приклад.
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Для зчитування символів використовують метод read() класу BufferedReader.
Сигнатура: int read()throws IOException
Для зчитування текстових рядків використовують метод readLine() класу BufferedReader.
Сигнатура: String read()throws IOException
Клас InputStreamReader переводить байти в символи, але дозволяє зчитувати лише один символ. Тому він “вкладається” в клас BufferedReader, який дозволяє зчитувати декілька символів. Для цього символи вхідного потоку заносяться в буфер, звідки зчитуються.
Консольний ввід в JDK 5.0. Клас Scanner
Починаючи з версії JDK 5.0 консольний ввід можна реалізувати через клас Scanner. Підключення пакету import java.util.*;
Загальна схема: на основі стандартного потоку вводу System.in створюється об'єкт класу Scanner, через який реалізується введення даних з консолі.
Деякі методи класу Scanner:
1. nextLine() – зчитування рядка
2. next() – зчитування слова 3. nextInt() – зчитування цілого числа
4. nextDouble() – зчитування дійсного числа
Використання діалогового вікна
Введення даних під час виконання програми можна реалізувати через діалогове вікно, що є елементом класу з бібліотеки Swing. Програма містить інструкцію import javax.swing.*;
Діалогове вікно викликається командою JOptionPane.showInputDialog(String)
Аргумент – текст, що відображається у вікні
Результат – текст, що вводиться користувачем в полі вікна
При виклику вікна створюється новий потік, який автоматично не завершується. Для завершення всіх потоків програму закінчуємо інструкцією System.exit(0).
Для перетворення тексту в числа використовують методи
Integer.parseInt(String)
Double.parseDouble(String)
Їх аргумент – рядок, що переводиться в числовий формат.
Робота з файлами
Для роботи з файлами використовують класи файлових потоків:FileInputStream
FileOutputStream
Конструктори класів:
FileInputStream(String) throws FileNotFoundException
FileOutputStream throws FileNotFoundException
Виключення FileNotFoundException – файл не знайдено
Після завершення роботи з файлом його треба закрити – для цього використовують метод close()
ПРИКЛАДИ
1. Приклад зчитування символів з консолі:
import java.io.*;class MySymbInput{
public static void main(String args[]) throws IOException{
char x;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Введіть декілька символів і натисніть <Enter>:");
do{
x=(char)br.read();
System.out.println(x);
}while(x!='x');
}
}
Результат:
Введіть декілька символів і натисніть <Enter>:
fgffkj
f
g
f
f
k
j
2. Приклад зчитування текстових рядків:
import java.io.*;class MyStringInput{
public static void main(String args[]) throws IOException{
String str="Ваше замовлення: ";
String s;
int count=0;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Що бажаєте:");
s=br.readLine();
while(!s.equalsIgnoreCase("Ні")){
count++;
str=str+"\n"+count+": "+s.toLowerCase();
System.out.println(str+"\n Ще щось?");
s=br.readLine();}
System.out.println("Дякуємо! Ваше замовлення прийнято!");
}
}
Результат:
Що бажаєте:
перше
Ваше замовлення:
1: перше
Ще щось?
друге
Ваше замовлення:
1: перше
2: друге
Ще щось?
ні
Дякуємо! Ваше замовлення прийнято!
3. Приклад використання класу Scanner:
import java.util.*;class MyNewScanner{
public static void main(String args[]){
Scanner inp=new Scanner(System.in);
String name;
int age;
System.out.println("Як Вас Звати?");
name=inp.nextLine();
System.out.println("Доброго дня, "+name+"!");
System.out.println("Скільки Вам років?");
age=inp.nextInt();
System.out.println(name+", Вам "+age+" років!");
}
}
Результат:
Як Вас Звати?
Оля
Доброго дня, Оля!
Скільки Вам років?
10
Оля, Вам 10 років!
4. Приклад використання діалогового вікна:
import javax.swing.*;class MyOptionPane{
public static void main(String args[]){
String name;
int age;
System.out.println("Як Вас звати?");
name=JOptionPane.showInputDialog("Вкажіть Ваше ім'я");
System.out.println("Доброго дня, "+name+"!");
System.out.println("Скільки Вам років?");
age=Integer.parseInt(JOptionPane.showInputDialog("Вкажіть Ваш вік"));
System.out.println(name+", Вам "+age+" років!");
name=JOptionPane.showInputDialog("Вкажіть Ваше ім'я");
System.out.println("Доброго дня, "+name+"!");
System.out.println("Скільки Вам років?");
age=Integer.parseInt(JOptionPane.showInputDialog("Вкажіть Ваш вік"));
System.out.println(name+", Вам "+age+" років!");
System.exit(0);
}
}
Результат:
Як Вас звати?
Доброго дня, Оля!
Скільки Вам років?
Оля, Вам 10 років!
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
//створюємо об'єктні змінні, які посилатимуться на наші потоки
FileInputStream in = null;
FileOutputStream out = null;
// При помилках читання/запису можуть генеруватися винятки, тож потрібно перехопити їх
// Наприклад, помилка може виникнути, при відсутності файлу first.txt у вказаному місці
try {
// створюємо вхідний і вихідний потік
// файл first.txt повинен вже існувати
// якщо second.txt не буде існувати,
// то буде створений при спробі запису
in = new FileInputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/first");
out = new FileOutputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/second.txt");
int c;
//Допоки з файлу first.txt не буде прочинато всі байти,
//читаємо байти з файлу first.txt і записуємо даний байт у second.txt
//якщо потік не повертає -1(не досягнено кінець файлу),
//то копіюємо наступний байт
while ((c = in.read()) != -1) {
out.write(c);
}
} finally { //дії коли не знайдено файли
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
import javax.swing.*;
class FindFellow{
public static void main(String args[]) throws IOException{
String fileName;
String name;
String s;
fileName=JOptionPane.showInputDialog("Вкажіть ім'я файлу:");
try{
FileInputStream fin=new FileInputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/"+fileName);
BufferedReader br=new BufferedReader(new InputStreamReader(fin));
name=JOptionPane.showInputDialog("Вкажіть прізвище співробітника:");
while(true){
s=br.readLine();
try{
if(s.equalsIgnoreCase(name)){
System.out.println("Прізвище : "+name);
System.out.println("Ім'я : "+br.readLine());
System.out.println("По-батькові: "+br.readLine());
System.out.println("Вік : "+br.readLine());
System.out.println("Тел. : "+br.readLine());
break;}
}catch(NullPointerException e){
System.out.println("Такого співробітника немає!");
break;}}
fin.close();
}catch(FileNotFoundException e){
System.out.println("Помилка доступу до файлу: "+e);}
System.exit(0);
}
}
}
Результат:
Як Вас звати?
Доброго дня, Оля!
Скільки Вам років?
Оля, Вам 10 років!
5. Приклад роботи з файлами:
Є два файли, необхідно скопіювати один файл у інший. Для цього ми створюємо два байтові потоки: вхідний потік, через який читатиметься наш файл first.txt і створюємо інший вихідний (output) потік, який записуватиме прочитані дані у second.txt. Для цього будемо використовувати два класи FileInputStream та FileOutputStream.
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
//створюємо об'єктні змінні, які посилатимуться на наші потоки
FileInputStream in = null;
FileOutputStream out = null;
// При помилках читання/запису можуть генеруватися винятки, тож потрібно перехопити їх
// Наприклад, помилка може виникнути, при відсутності файлу first.txt у вказаному місці
try {
// створюємо вхідний і вихідний потік
// файл first.txt повинен вже існувати
// якщо second.txt не буде існувати,
// то буде створений при спробі запису
in = new FileInputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/first");
out = new FileOutputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/second.txt");
int c;
//Допоки з файлу first.txt не буде прочинато всі байти,
//читаємо байти з файлу first.txt і записуємо даний байт у second.txt
//якщо потік не повертає -1(не досягнено кінець файлу),
//то копіюємо наступний байт
while ((c = in.read()) != -1) {
out.write(c);
}
} finally { //дії коли не знайдено файли
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
6. Приклад зчитування з файлу:
import java.io.*;import javax.swing.*;
class FindFellow{
public static void main(String args[]) throws IOException{
String fileName;
String name;
String s;
fileName=JOptionPane.showInputDialog("Вкажіть ім'я файлу:");
try{
FileInputStream fin=new FileInputStream("C:/Users/HOME/workspace/inputOutput/src/inputOutput/"+fileName);
BufferedReader br=new BufferedReader(new InputStreamReader(fin));
name=JOptionPane.showInputDialog("Вкажіть прізвище співробітника:");
while(true){
s=br.readLine();
try{
if(s.equalsIgnoreCase(name)){
System.out.println("Прізвище : "+name);
System.out.println("Ім'я : "+br.readLine());
System.out.println("По-батькові: "+br.readLine());
System.out.println("Вік : "+br.readLine());
System.out.println("Тел. : "+br.readLine());
break;}
}catch(NullPointerException e){
System.out.println("Такого співробітника немає!");
break;}}
fin.close();
}catch(FileNotFoundException e){
System.out.println("Помилка доступу до файлу: "+e);}
System.exit(0);
}
}