PROGRAMARE ORIENTATĂ
OBIECT
Limbajul şi platforma Java
Programare II. C7
Motto
“People think that computer science is the art of
geniuses but the actual reality is the opposite,
just many people doing things that build on
each other, like a wall of mini stones.”
Donald Knuth (computer scientist)
2
Persistența orientată-obiect
● Problema:
○ Definiție: restaurarea obiectelor (stărilor obiectelor) între sesiuni
diferite (secvențiale, paralele) ale aplicației în care sunt
instanțiate/re-activate.
○ Concept: “Persistența” obiectelor.
● Categorii, soluții și tehnologii:
○ Formatul stării obiectelor (formatul datelor) în mediul persistent:
■ format brut binar - binary code;
■ format semi-structurat - character/textual (CSV, XML, JSON);
■ format structurat - SQL.
○ Mediul de persistență:
■ bazat pe fișiere;
■ bazat pe baze de date (SQL sau NoSQL).
● Componenta arhitecturală responsabilă de încapsularea
soluției și expunerea abstractă a serviciului de persistență:
○ Șablonul DAO (Data Access Object) sau Repository
3
Studiu de caz 1: File-based Repository*
● Format date:
○ Java Bytecode (binar)
● Tehnologii implicate
○ FileInput/OutputStream API
○ java.io.File API
● Componenta arhitecturală:
○ Clasa DAO:
■ ProiecteSerializabileDAO
○ Mediu concret de persistență:
■ Fișier local: Proiecte_Releases_Aggregate.ser
* Capitolul 7. Platforma Java: I/O API și lucru cu fișiere
4
Studiu de caz 2: CSV File-based Repository*
● Format date:
○ Semistructurat: CSV
● Tehnologii implicate
○ FileReader -FileWriter
○ BufferedReader - BufferedWriter
○ java.io.File API
● Componenta arhitecturală:
○ Clasa DAO:
■ ProiecteCsvDAO
○ Mediu concret de persistență:
■ Fișier local: Proiecte_Releases_Aggregate.csv
* Capitolul 7. Platforma Java: I/O API și lucru cu fișiere
5
Studiu de caz 3: SQL-based Repository*
● Format date:
○ Structurat: SQL
● Tehnologii implicate
○ JDBC
● Componenta arhitecturală:
○ Clasa DAO:
■ ProiecteJdbcDAO
○ Mediu concret de persistență:
■ Server baze de date: PostgreSQL
* Capitolul 8. Conectivitate baze de date SQL cu JDBC
6
Capitolul 7. Platforma Java:
I/O API și lucru cu fișiere
Java IO, Java File NIO
Agenda
❏ (1) Studiu de caz (problema reprezentativă)
❏ (2) Java I/O: Stream-uri de Input/Output
❏ Overview Stream-uri sau canale de transmitere IO
❏ Principalele API-uri:
❏ Input/OutputStream, FileReader/Writer
❏ Probleme comune
❏ Citire/Scriere linii în fișiere
❏ Citire/Scriere date (primitive) în fișiere
❏ Citire/Scriere obiecte în fișiere (serializare obiecte)
❏ (3) Java File I/O
❏ Overview File IO și NIO 2.0
❏ Principalele API-uri:
❏ File, Files, Path, Paths, FileSystem
❏ Probleme comune
❏ Use-case cu directoare, use-case cu fișiere
8
Java Development Platforms
● Java Standard Platform cu Java Runtime Engine
● Jakarta/Java Enterprise Edition Platform
● Android Mobile Platform cu Android Runtime
9
Cadrul de lucru și bibliotecile Java I/O
● Interfețele de programare (API-uri) ale platformei Java
Standard (parte a JDK) privind canalele I/O:
○ Java I/O;
○ Java File I/O (incl. NIO.2.0).
● Problema avută în vedere: comunicarea/transmiterea
datelor din/spre spațiul de memorie tranzient al JRE
din/spre (re)surse externe ce pot asigura persistență:
○ fișiere locale;
○ consola implicită a mediului de execuție;
○ (re)surse la distanță (în rețea sau remote).
10
1. Studiu de caz: problema concretă
● Problema: copiere date din fișier sursă către fișier
destinație.
● Etape lucru cu date I/O
○ deschidere flux intrare din fișier sursă: FileInputStream,
FileReader;
○ citire date în buffer intern: InputStream;
○ localizare/creare fișier destinație: FileOutputStream,
FileWriter;
○ scriere date din buffer intern în fișier extern: OutputStream;
○ închidere resurse accesate try(with-resources){ };
○ test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: Sys.out.
● Clasa de testare: Test0_Init_IOStreams
11
2. Java I/O: Stream-uri de Input/Output
● Privire generală stream-uri sau canale de transmitere IO.
● Principalele API-uri:
○ InputStream/OutputStream,
○ Reader/Writer.
● Probleme comune
○ Citire/Scriere linii în fișiere
○ Citire/Scriere date (primitive) în fișiere
○ Citire/Scriere obiecte în fișiere: persistență prin
serializare obiecte în fișiere.
12
Java I/O Streams
13
Modelul Standard Java I/O
● Categoriile de canale de comunicare constau în:
○ streams (fluxuri de intrare sau ieșire)
○ pipes (fluxuri de intrare-ieșire).
● Categoriile de (re)surse accesate constau în:
○ surse de date
○ destinații (sinks).
● Formatele de comunicare a datelor constau în:
○ octeți (bytes);
○ caractere;
○ valori primitive;
○ obiecte (în format binar).
14
Clase comune
pentru
Stream-uri I/O
15
Clase pentru stream-uri de intrare
Sursa: javatpoint at https://www.javatpoint.com/
16
Clase pentru stream-uri de intrare
Sursa: javatpoint at https://www.javatpoint.com/
17
Stream-urile Standard ale JRE
Sursa: geeksforgeeks at https://www.geeksforgeeks.org/
18
Stream-urile Standard ale JRE
public class System {
public static PrintStream out; // the standard output
public static InputStream in; // the standard input
public static PrintStream err; // the standard error
// ... ...
}
19
Overview Stream-uri de Input/Output
● Un stream I/O este un canal de preluare|transmitere date
din|spre o sursă|destinație (sink).
● Categorii de date I/O pot fi:
○ brute: bytes, characters;
○ structurate/tipizate: primitive(numerice), șiruri de caractere;
○ obiecte: instanțe clase-tipuri abstracte de date.
● Tipuri de stream-uri I/O pot fi
○ Stream-uri orientate pe date binare (bytes):
■ de intrare/citire: InputStream;
■ de ieșire/scriere: OutputStream;
○ Stream-uri orientate pe caractere: Readers, Writers.
● Categorii de surse|destinații (aplicații)
○ orientate pe fișiere;
○ orientate pe consolă;
○ bazate pe socket-uri (comunicare în rețea - la distanță - remote).
20
Compunere Stream-uri
Sursa: Oracle University at oracle.com/education
21
Înlănțuire stream-uri: combinații comune
Stream inițial Stream intermediar Stream final
FileInputStream BufferedInputStream DataInputStream
FileOutputStream BufferedOutputStream DataOutputStream
FileReader BufferedReader
FileWriter BufferedWriter
FileInputStream BufferedInputStream ObjectInputStream
FileOutputStream BufferedOutputStream ObjectOutputStream
22
Modelul Standard Java I/O: Categorii de stream-uri
● După criteriul direcției de comunicare: stream-urile de
intrare/ieșire se împart în:
○ InputStream, Reader;
○ OutputStream, Writer;
● După criteriul formatului se împart în:
○ binar: InputStream, OutputStream;
■ ObjectInputStream, ObjectOutputStream;
○ bazat pe caractere: Reader, Writer.
● După criteriul naturii sursei/destinației se împart în:
○ pentru fișiere locale: FileInputStream, FileOutputStream; FileReader,
FileWriter;
○ pentru consola standard: System.in, System.out;
○ pentru rețea: Socket::getInputStream(), Socket::getOutputStream().
23
InputStream API
● Operații citire date binare:
○ int read() citește un singur octet sau -1;
○ int read(byte[ ] buffer) citește conținut din fișier în buffer;
○ int read(byte[ ] buffer, int offset, int length).
● Operații de gestiune flux de date:
○ int available()
○ void close()
○ long skip(long l)
24
OutputStream API
● Operații scriere date binare
○ void write(int c) scrie un singur octet;
○ void write(byte[ ] buffer) scrie conținut buffer în fișier;
○ void write(byte[ ] buffer, int offset, int length);
● Operații de gestiune flux de date
○ void flush();
○ void close();
25
Reader API
● Operații citire date de tip caracter
○ int read() citește un singur caracter sau -1;
○ int read(char[ ] buffer) citește conținut din fișier în buffer;
○ int read(char[ ] buffer, int offset, int length).
● Operații de gestiune flux de date
○ void close()
○ void ready()
○ long skip(long l)
26
Writer API
● Operații scriere date de tip caracter
○ void write(int c) scrie un singur caracter;
○ void write(char[ ] buffer) scrie conținut buffer în fișier;
○ void write(char[ ] buffer, int offset, int length);
○ void write(String string) scrie valoare String în fișier;
○ void write(String string, int offset, int length);
● Operații de gestiune flux de date
○ void flush();
○ void close();
27
Use case (1): Stream-uri pentru
citire/scriere linii în fișiere
● Problema: citire/scriere conținut din/în fișiere sursă ca
linii-șiruri de caractere delimitate.
● Etape flux I/O:
○ Deschidere flux intrare din fișier sursă: FileReader;
○ Citire date în buffer intern: BufferedReader :: readLine();
○ Localizare/creare fișier destinație: FileWriter;
○ Scriere date din buffer intern în fișier extern:
BufferedWriter :: append(), newLine();
○ Închidere resurse accesate try(with-resources){ };
○ Test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test1_CharLinesStreams
28
Use case (2): Stream-uri pentru
citire/scriere date în fișiere
● Problema: citire/scriere date din/în fișiere sursă și
afișare consolă
● Etape flux I/O
○ Deschidere flux intrare fișier sursă: FileInputStream;
○ Citire date în buffer intern:
■ DataInputStream :: readInt(), readUTF();
■ Scanner :: nextInt(), next();
○ Localizare/creare fișier destinație: FileOutputStream;
○ Scriere date din buffer intern în fișier extern:
DataOutputStream :: writeInt(), writeUTF();
○ Închidere resurse accesate try(with-resources){ };
○ Test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test2_DataStreams
29
Use case (3.v1): Stream-uri pentru
citire/scriere obiecte în fișiere
● Problema: serializare obiecte
● Etape flux I/O
○ Deschidere flux intrare fișier sursă: FileInputStream;
○ Citire date în buffer intern:
■ ObjectInputStream :: readObject();
■ Scanner;
○ Localizare/creare fișier destinație: FileOutputStream;
○ Scriere date din buffer intern în fișier extern:
ObjectOutputStream :: writeObject();
○ Închidere resurse accesate try(with-resources){ };
○ Test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test3_ObjectFileStreams
30
Use case (3.v2): Stream-uri pentru
citire/scriere obiecte ObjectStream-DAO
● Problema: serializare obiecte
● Etape flux DAO în clasa ProiecteSerializabileDAO
○ Inițializare DAO
■ FileInputStream
○ Interogare DAO
■ FileInputStream
■ ObjectInputStream
○ Salvare obiecte
■ ObjectOutputStream
■ FileOutputStream
○ Test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test3_DAO_ObjectStream
31
Use case (3.v3): Stream-uri pentru
citire/scriere obiecte File Reader/Writer DAO
● Problema: serializare obiecte
● Etape flux DAO în clasa ProiecteCsvDAO
○ Inițializare DAO
■ FileWriter
○ Interogare DAO
■ FileReader
■ BufferedReader
○ Salvare obiecte
■ BufferedWriter
■ FileWriter
○ Test flux I/O:
■ deschidere fișier extern;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test3_DAO_CsvFormat
32
2. Lucru cu (sisteme de) fișiere
● Overview Java File I/O API (incl. NIO)
● Principalele API-uri:
○ java.io.File,
○ java.nio.Files,
○ java.nio.Path,
○ java.nio.Paths,
○ java.nio.FileSystem
● Probleme comune
○ Use-case gestiune fluxuri I/O cu instanțe File,
○ Use-case gestiune fluxuri I/O cu instanțe Path.
33
Concepte privind lucru cu sistemele de fișiere
● Sisteme de fișiere (niv. S.O)
● Căi
● Fișiere
● Directoare
● Symbolic-Links (legături-simbolice)
○ Soft-Links
○ Hard-Links
34
Overview Java File I/O
java.io.File
Java Char Sequences
java.io.File
35
Overview Java File I/O
java.io.File
ObjectInputStream BufferedInputStream FileInputStream
ObjectOutputStream BufferedOutputStream FileOutputStream
java.io.File
36
Overview Java File I/O
java.io.File
Java Data Types
DataInputStream BufferedInputStream FileInputStream
DataOutputStream BufferedOutputStream FileOutputStream
java.io.File
37
java.io.File Class API
Reprezentare fișiere și directoare
Nume operație Descriere
new File(String pathname) Constructor: reprezentare internă Java obiect-fișier sau director
după calea pathname
boolean isAbsolute() Verifică dacă calea pathname este absolută sau relativă
boolean isFile() Verifică dacă pathname corespunde unui fișier
boolean isDirectory() Verifică dacă pathname corespunde unui director
String getName() Returnează numele fișierului/directorului din pathname
String getParent() Returnează numele directorului părinte din pathname
Path toPath() Returnează pathname ca șir de caractere
File[] listFiles() Returnează un array File[] pentru un director obținut din pathname
boolean exists() Verifică dacă există un fișier/director corespunzător căii pathname
38
java.io.File Class API
Manipulare fișiere și directoare
Nume operație Descriere
new File(String pathname) Constructor: reprezentare internă Java obiect-fișier sau director
după calea pathname
boolean createNewFile() Creează un fișier nou gol după calea pathname și returnează true
pentru success
boolean mkdir() Creează un director nou gol după calea pathname și returnează
true pentru success
boolean delete() Șterge director/fișier corespunzător căii pathname
boolean renameTo(File dest) Redenumește fișier după calea pathname a fișierului dest
39
Java File NIO API
● Căile (către fișiere sau directoare) sunt reprezentate cu
ajutorul claselor Path și Paths.
● Fișierele sunt manipulate cu ajutorul clasei Files.
● Reprezentarea sistemului de fișiere cu FileSystem.
40
java.nio.file.Path Class API
Reprezentare fișiere și directoare
Nume operații statice Descriere java.io.File operation
Path Paths.get(pathname) Metodă factory statică: reprezentare obiect-fișier new File(pathname)
sau director după calea abstractă pathname
Path getFileName() Returnează numele fișierului/directorului unei getName()
instanțe Path
Path getParent() Returnează numele directorului părinte al unei getParent()
instanțe Path
Path getRoot() Returnează reprezentarea directorului rădăcină al
unei instanțe Path
boolean isDirectory() Returnează true instanța Path dacă localizează un isDirectory()
director
boolean isRegularFile() Returnează true instanța Path dacă localizează un isFile()
fișier simplu
41
java.nio.file.Files Class API
Manipulare fișiere și directoare
Nume operații statice Descriere java.io.File operation
Path createFile(Path Creează fișier după calea filePath createNewFile()
filePath,FileAttribute<?>... attrs)
Path createDirectory(Path dirPath, Creează director după calea dirPath mkDir()
FileAttribute<?>... attrs)
boolean exists(Path p) Verifică dacă fișierul reprezentat prin exists()
parametrul de intrare p de tip Path există
boolean notExists(Path p)
void delete(Path p) Șterge fișierul/director reprezentat prin delete()
parametrul de intrare p de tip Path
boolean deleteIfExists(Path p)
Path copy(Path src, Path dest, Copiază fișierul/director reprezentat prin parametrul src în dest cu
CopyOption opt...) opțiunile posibile REPLACE_EXISTING, COPY_ATTRIBUTES,
NOFOLLOW_LINKS
Path move(Path src, Path dest, Mută fișierul/director reprezentat prin renameTo()
CopyOption opt...) parametrul src în dest
42
java.nio.file.Files Class API
Manipulare fișiere și directoare
Nume operație statice Descriere java.io.File operation
Stream<Path> list(Path dirPath) Returnează un Stream<Path> ce poate fi listFiles()
parcurs cu un Consumer forEach()
Stream<Path> walk(Path dirPath, Returnează un Stream<Path> ce poate fi
FileVisitOption... options) parcurs cu un Consumer forEach()
“depth-first”
List<String> readAllLines(Path txtFile) Returnează un List<String> cu liniile din
fișierul text
Stream<String> lines(Path txtFile) Returnează un Stream<String> cu liniile
din fișierul text ce pot fi parcurse cu un
Consumer forEach()
BufferedReader Returnează o instanță BufferedReader
newBufferedReader(Path path) pentru a citi fișierul reprezentat de
parametrul path
BufferedWriter Returnează o instanță BufferedWriter
newBufferedWriter(Path path) pentru a scrie în fișierul reprezentat de
parametrul path
43
java.nio.file.FileSystem API
Interfața suport pentru obiecte Path
Nume operație Descriere
FileSystem Returnează reprezentarea-instanță a sistemului de fișiere local
FileSystems.getDefault()
Path getPath(String pathname) Returnează instanța reprezentând obiectul-fișier sau director
după calea abstractă pathname
String getSeparator() Returnează ca șir caracterul separator de cale specific sistemului
de fișiere curent
Iterable<Path> getRootDirectories() Returnează un iterator pentru a parcurge căile reprezentând
directoarele root ale sistemului local de fișiere (partiționat).
44
Cazuri comune de utilizare Java File NIO
● Directoare
○ Consultare
○ Creare
● Fișiere
○ Căutare
○ Copiere, Mutare
● Fișiere de proprietăți
○ AppConfig.properties
45
Use case 4: java.io.File
● Creare instanță File din string path
○ construire InputStream, OutputStream pentru a citi/scrie un File
● Etape flux I/O
○ Deschidere flux intrare fișier sursă: FileInputStream din File;
■ creare fișier File :: createNewFile();
○ Citire date în buffer intern:
■ ObjectInputStream; Scanner;
○ Localizare fișier destinație: FileOutputStream din File;
○ Scriere date din buffer intern în fișier extern:
ObjectInputStream;
○ Închidere resurse accesate try(with-resources){ };
○ Test flux I/O: deschidere fișier extern ;
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test4_DataStreamsFileFromPath
46
Use case 5: Paths and Files
● Crează fișier folosind o instanță Path, scrie cu
Files.newBufferedWriter(Path), citește cu
Files.lines(Path)
● Etape flux I/O
○ Localizare fișier cu: Paths.get(Path);
■ Creare fișier cu Files.createFile(Path);
○ Citire date Files.lines();
○ Scriere date din buffer intern BufferedWriter
■ Obținut cu Files.newBufferedWriter(Path)
○ Închidere resurse accesate try(with-resources){ };
○ Test flux I/O:
■ localizare fișier extern Paths.get(Path);
■ afișare conținut la consola standard: PrintStream.
● Clasa de testare: Test5_StringLineFileFromPath
47
Referinte și tutoriale on-line
Java IO.APIs
● Tutorialspoint: JavaIO
● How To Do In Java: Java IO Tutorial
● Baeldung: JavaIO Tutorial
● JournalDev: JavaIO Tutorial și Java NIO Tutorial
● Oracle Technology Network Essentials Java IO
● Jata-T-Point Java I/O Tutorial
● DZone
○ Java File I/O Basics
○ Java IO and NIO
48