Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
/
Звіт
З лабораторної роботи №6
З дисципліни: «Кросплатформні засоби програмування»
На тему: «Файли»
Львів 2018
Мета роботи: Оволодіти навиками використання засобів мови Java для роботи з потоками і файлами.
ТЕОРЕТИЧНІ ВІДОМОСТІ
Бібліотека класів мови Java має більше 60 класів для роботи з потоками. Потаками у мові Java називаються об’єкти з якими можна здійснювати обмін даними. Цими об’єктами найчастіше є файли, проте ними можуть бути стандартні пристрої вводу/виводу, блоки пам’яті і мережеві підключення тощо. Класи по роботі з потоками об’єднані у кілька ієрархій, що призначені для роботи з різними видами даних, або забезпечувати додаткову корисну функціональність, наприклад, підтримку ZIP архівів.
Класи, що спадкуються від абстрактних класів InputStream і OutputStream призначені для здійснення байтового обміну інформацією. Підтримка мовою Java одиниць Unicode, де кожна одиниця має кілька байт, зумовлює необхідність у іншій ієрархії класів, що спадкується від абстрактних класів Reader і Writer. Ці класи дозволяють виконувати операції читання/запису не байтних даних, а двобайтних одиниць Unicode.
Принцип здійснення читання/запису даних нічим не відрізняється від такого принципу у інших мовах програмування. Все починається з створення потоку на запис або читання після чого викликаються методи, що здійснюють обмін інформацією. Після завершення обміну даними потоки необхідно закрити щоб звільнити ресурси.
Принципи роботи з файловими потоками
Для створення файлових потоків і роботи з ними у Java є 2 класи, що успадковані від InputStream і OutputStream це - FileInputStream і FileOutputStream. Як і їх суперкласи вони мають методи лише для байтового небуферизованого блокуючого читання/запису даних та керуванням потоками. На відміну від, наприклад, мови програмування С, де для виконання усіх можливих операцій з файлами необхідно мати один вказівник на FILE у мові Java реалізовано інший набагато складніший і гнучкіший підхід, який дозволяє формувати такі властивості потоку, які найкраще відповідають потребам рішення конкретної задачі. Так у Java розділено окремі функціональні можливості потоків на різні класи. Компонуючи ці класи між собою і досягається необхідна кінцева функціональність потоку. Так одні класи, як FileInputStream, забезпечують елементарний доступ до файлів, інші, як PrintWriter, надають додаткової функціональності по високорівневій обробці даних, що пишуться у файл. Ще інші, наприклад, BufferedInputStream забезпечують буферизацію. Таким чином, наприклад, щоб отримати буферизований файловий потік для читання інформації у форматі примітивних типів (char, int, double,...) слід створити потік з одночасним сумісним використанням функціональності класів FileInputStream, BufferedInputStream і DataInputStream. Для цього слід здійснити наступний виклик:
DataInputStream din = new DataInputStream(
new BufferedInputStream(
new FileInputStream)));
Класи типу BufferedInputStream, DataInputStream, PushbackInputStream (дозволяє читати з потоку дані і повертати їх назад у потік) успадковані від класу FilterInputStream. Вони виступають так званими фільтрами, що своїм комбінуванням забезпечують додаткову лише необхідну функціональність при читанні даних з файлу. Аналогічний підхід застосовано і при реалізації класів для обробки текстових даних, що успадковані від Reader і Writer.
Файли з довільним доступом
Керування файлами з можливістю довільного доступу до них здійснюється за допомогою класу RandomAccessFile. Відкривання файлу в режимі запису і читання/запису здійснюється за допомогою конструктора, що приймає 2 параметри – посилання на файл (File file) або його адресу (String name) та режим відкривання файлу (String mode):
RandomAccessFile(File file, String mode);
RandomAccessFile(String name, String mode).
Параметр mode може приймати такі значення:
"r" – читання;
"rw" – читання/запис;
"rws" – читання/запис даних з негайним синхронним записом змін у файл або метадані файлу;
"rwd" – читання/запис даних з негайним синхронним записом змін у файл, метадані файлу не міняються одразу.
Файли, що керуються класом RandomAccessFile, оснащені вказівником на позицію наступного байту, що має читатися або записуватися. Для того, щоб перемістити даний вказівник на довільну позицію в межах файлу використовується метод void seek(long pos). Параметр long pos визначає номер байту, що має читатися або записуватися.
Щоб дізнатися поточну позицію вказівника на позицію наступного байту слід використати метод long getFilePointer().
Для визначення довжини файлу використовується метод long length(), а для закриття файлу – void close().
Для читання і запис даних клас RandomAccessFile реалізує методи інтерфейсів DataInput і DataOutput, які описані у попередньому пункті.
Довільний доступ до файлу є найповільнішим способом доступу до файлів. Трішки швидшим є звичайний потік даних і набагато швидшим є буферизований потік даних.
Хід роботи:
Завдання:
1) Створити клас, що реалізує методи читання/запису у текстовому і двійковому форматах результатів роботи класу, що розроблений у лабораторній роботі No5. Написати програму для тестування коректності роботи розробленого класу.
2) Для розробленої програми згенерувати документацію.
Варіант: 7) y=ctg(x)/sin(7x-1)
Код програми:
package KI43.Husak.Lab6;
import java.io.*;
import java.util.*;
public class FioApp {
public static void main(String[] args) throws FileNotFoundException, IOException
{
CalcWFio obj = new CalcWFio();
Scanner s = new Scanner(System.in);
System.out.print("Enter data: ");
double data = s.nextDouble();
obj.calculate(data);
System.out.println("Result is: " + obj.getResult());
obj.writeResTxt("labs6.txt");
obj.writeResBin("labs6.bin");
obj.readResBin("BinRes.bin");
System.out.println("Result is: " + obj.getResult());
obj.readResTxt("labs5.txt");
System.out.println("Result is: " + obj.getResult());
s.close();
}
}
class CalcWFio
{
public void writeResTxt(String fName) throws FileNotFoundException
{
PrintWriter f = new PrintWriter(fName);
f.printf("%f ",result);
f.close();
}
public void readResTxt(String fName)
{
try
{
File f = new File (fName);
if (f.exists())
{
Scanner s = new Scanner(f);
result = s.nextDouble();
s.close();
}else
throw new FileNotFoundException("File " + fName + "notfound");
}catch (FileNotFoundException ex)
{
System.out.print(ex.getMessage());
}
}
public void writeResBin(String fName) throws FileNotFoundException, IOException
{
DataOutputStream f = new DataOutputStream(new FileOutputStream(fName));
f.writeDouble(result);
f.close();
}
public void readResBin(String fName) throws FileNotFoundException, IOException
{
DataInputStream f = new DataInputStream(new FileInputStream(fName));
result = f.readDouble();
f.close();
}
public void calculate(double x)
{
result = (1/Math.tan(x))/(Math.sin(7*x-1));
}
public double getResult()
{
return result;
}
private double result; }
/
Рис. 1 Результат роботи програми
/
Рис. 2 Результат роботи програми, записаний у файл
/
Рис. 3 Документація до классу FioApp, згенерована автоматично, з допомогою спеціальних коментарів
/
/
Рис. 4 Документація до классу CalcWFio, згенерована автоматично, з допомогою спеціальних коментарів
Висновок: Під час виконання даної лабораторної роботи я оволодів навиками використання засобів мови Java для роботи з потоками і файлами.