Diferència entre revisions de la pàgina «DAM-M3-UF5. Lectura i escriptura. Fitxers»
(Es crea la pàgina amb «Hi ha múltiples ocasions on cal introduir dades a un programa o mostra-les a la sortida, per exemple: Línia de comandes Formulari amb elements gràfics Fitxers Pip...».) |
(→XML) |
||
(29 revisions intermèdies per 4 usuaris que no es mostren) | |||
Línia 1: | Línia 1: | ||
+ | torna [[ M3 - Programació ]] | ||
+ | |||
+ | == Lectura i escriptura == | ||
+ | |||
Hi ha múltiples ocasions on cal introduir dades a un programa o mostra-les a la sortida, per exemple: | Hi ha múltiples ocasions on cal introduir dades a un programa o mostra-les a la sortida, per exemple: | ||
− | Línia de comandes | + | * Línia de comandes |
+ | |||
+ | * Formulari amb elements gràfics | ||
+ | |||
+ | * Fitxers | ||
+ | |||
+ | * Pipes o sockets | ||
+ | |||
+ | Java tracta la entrada i sortida d'informació establint uns corrents o fluxes ('''stream'''), a través dels quals trasllada blocs de dades ('''buffer'''). | ||
+ | |||
+ | Aquests fluxes sempre són binaris evidentment, però Java ofereix dos possibles tractaments: | ||
+ | |||
+ | * '''Fluxe binari''' (bytes), classes <code class='java>InputStream</code>, <code class='java'>OutputStream</code> | ||
+ | * '''Fluxe de caràcters''' , classes <code class='java>Reader</code>, <code class='java>Writer</code> | ||
+ | |||
+ | |||
+ | === Mètodes bàsics === | ||
+ | |||
+ | A través de la entrada i sortida estàndard | ||
+ | |||
+ | * <code class='java>System.in</code>, és un fluxe binari (<code class='java>InputStream</code>), que recull les dades entrades per consola | ||
+ | * <code class='java>System.out</code>, és un fluxe binari (<code class='java>OutputStream</code> -> <code class='java>PrintStream</code>) amb algunes funcionalitats de tractament, converteix caràcters a bytes segons codificació de la plataforma. | ||
+ | |||
+ | |||
+ | === La classe Scanner === | ||
+ | |||
+ | La classe <code class='java>Scanner</code> és una funció d'utilitat simple per a la lectura de dades tipus primitius (int, <code class='java'>String</code>, etc...) o qualsevol objecte que implementi <code class='java>Readable</code>. | ||
+ | |||
+ | Trenca la lectura segons el delimitador (Per defecte un espai en blanc, encara que es pot modificar) | ||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | Scanner scanner = new Scanner(System.in); | ||
+ | |||
+ | System.out.print("Escriu un text: "); | ||
+ | String dada = scanner.next(); | ||
+ | System.out.println("Has escrit: " + dada); | ||
+ | |||
+ | scanner.close(); | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | A més implementa la interface <code>Iterator</code> de manera que permet gestionar la lectura amb les operacions de control dels iteradors | ||
+ | |||
+ | * <code class='java>hasNext()</code> | ||
+ | * <code class='java>next()</code> | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | do { | ||
+ | System.out.print("Escriu \"Fi\" per acabar: "); | ||
+ | dada = scanner.next(); | ||
+ | |||
+ | } while (!dada.equals("Fi")); | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | També permet definir diferents tipus d'entrada com fitxers o cadenes de text, i té mètodes específics per a la lectura d'enters, decimals, etc... | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | Scanner scanner = new Scanner(System.in); | ||
+ | |||
+ | String dada = "aaa bbb ccc ddd"; | ||
+ | do { | ||
+ | dada = scanner.next(); | ||
+ | System.out.println( "Conté: " + dada); | ||
+ | } while (scanner.hasNext()); | ||
+ | |||
+ | dada = "1 2 3 4"; | ||
+ | do { | ||
+ | System.out.println( "Conté: " + scanner.nextInt()); | ||
+ | } while (scanner.hasNextInt()); | ||
+ | |||
+ | scanner.close(); | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | === Readers / Writers === | ||
+ | |||
+ | A part dels sistemes anteriors, Java proporciona una capa d'utilitats entre la entrada i l'usuari que permet fer un tractament semblant independentment del tipus d'entrada o sortida que es faci servir. | ||
+ | |||
+ | Les classes utilitzades per al tractament de fluxes de caràcters hereten de <code class='java>java.io.Reader</code> i de <code class='java>java.io.Writer</code> | ||
+ | |||
+ | |||
+ | '''Exemple lectura de consola''', obliga a gestionar les excepcions | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | public static void main(String[] args) throws IOException { | ||
+ | |||
+ | InputStreamReader isReader = new InputStreamReader(System.in); // Entrada estandard | ||
+ | |||
+ | BufferedReader bReader = new BufferedReader(isReader); // Buffer | ||
+ | |||
+ | String text = bReader.readLine(); // Lectura d'una linia, String | ||
+ | |||
+ | int num = Integer.parseInt(bReader.readLine()); // Lectura d'una linia i conversió a enter | ||
+ | |||
+ | ... | ||
+ | |||
+ | bReader.close(); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | '''Exemple entrada de fitxers''', observar que també usa la classe ''BufferedReader'', una vegada inicialitzat aquest el tractament és independent del tipus d'entrada. | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | File fitxer = new File("nom"); // Adreçament relatiu | ||
+ | FileReader fReader = null; // Lector del fitxer | ||
+ | BufferedReader bReader = null; // Buffer | ||
+ | String linea; | ||
+ | |||
+ | try { | ||
+ | fReader = new FileReader(fitxer); // Inicialitza lector amb el fitxer a llegir | ||
+ | bReader = new BufferedReader(fReader); // Inicialitza buffer amb el lector (entrada) | ||
+ | |||
+ | while ((linea = bReader.readLine()) != null) { | ||
+ | System.out.println(linea); | ||
+ | } | ||
+ | } catch (FileNotFoundException e) { | ||
+ | System.out.println("Fitxer no existeix"); | ||
+ | } catch (IOException e) { | ||
+ | System.out.println(e.getMessage()); | ||
+ | } finally { | ||
+ | if (bReader != null) { | ||
+ | bReader.close(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | |||
+ | '''Exemple escriptura a fitxer''' | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | boolean append = true; | ||
+ | FileWriter fWriter = new FileWriter("nom", append); | ||
+ | |||
+ | boolean autoFlush=true; | ||
+ | PrintWriter pWriter = new PrintWriter(fWriter, autoFlush); | ||
+ | |||
+ | try { | ||
+ | int i = 0; | ||
+ | while (i < 10) { | ||
+ | pWriter.println("linia " + i++); | ||
+ | } | ||
+ | } catch (Exception e) { | ||
+ | System.out.println(e.getMessage()); | ||
+ | } finally { | ||
+ | pWriter.close(); | ||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | === Fitxers === | ||
+ | |||
+ | Els fitxers permeten emmagatzemar dades, aquestes dades poden ser de dos tipus: | ||
+ | * '''Text''', dades alfanumèriques | ||
+ | * '''Binari''', dades en binari | ||
+ | |||
+ | ==== Modes d'accés. Accés aleatori ==== | ||
+ | |||
+ | L'accés a les dades dels fitxers es pot fer de dues maneres | ||
+ | * '''Seqüencialment''', s'obre el fitxer i es llegeix les dades des de l'inici. Aquest tipus de fitxers no tenen cap estructura especial. | ||
+ | |||
+ | Java proporciona la classe <code class='java>File</code> per a l'accés seqüencial. Les dades poden ser tant text com binàries. Aquesta classe representa directament els objectes del sistema de fitxers i les seves propietats. | ||
+ | |||
+ | * De forma '''aleatòria''', s'obre el fitxer i s'accedeix a una dada concreta. Per a permetre aquest tipus d'accés cal definir certes estructures especials on desar els apuntadors (índexs, ''file pointers''). | ||
+ | |||
+ | Java proporciona la classe <code class='java>RandomAccessFile</code> per a l'accés aleatori, els fitxers són '''binaris''' i tenen un '''índex''' que permet accedir a posicions concretes. Aquesta classe és una abstracció més allunyada que <code class='java>File</code> dels objectes del sistema de fitxers, doncs incorpora estructures pròpies que gestiona Java. | ||
+ | |||
+ | |||
+ | ==== Classe File ==== | ||
+ | |||
+ | La classe <code class='java>File</code> permet treballar amb fitxers i directoris. | ||
+ | |||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | File file = new File("fitxer"); | ||
+ | |||
+ | if (file.exists()) { | ||
+ | System.out.println("el fitxer existeix"); | ||
+ | } else { | ||
+ | System.out.println("el fitxer NO existeix, el creem"); | ||
+ | file.createNewFile(); | ||
+ | } | ||
+ | |||
+ | System.out.println("path: " + file.getPath()); // fitxer | ||
+ | System.out.println("path absolut: " + file.getAbsolutePath()); // {path_to_file}/fitxer | ||
+ | System.out.println("ultima modificació : " + new Date(file.lastModified())); | ||
+ | System.out.println("longitud : " + file.length()); | ||
+ | |||
+ | file.setExecutable(true); | ||
+ | |||
+ | if (file.canExecute()) { | ||
+ | System.out.println("execució"); | ||
+ | } | ||
+ | if (file.canRead()) { | ||
+ | System.out.println("lectura"); | ||
+ | } | ||
+ | if (file.canWrite()) { | ||
+ | System.out.println("escriptura"); | ||
+ | } | ||
+ | if (file.isFile()) { | ||
+ | System.out.println("fitxer"); | ||
+ | } | ||
+ | if (file.isDirectory()) { | ||
+ | System.out.println("directori"); | ||
+ | } | ||
+ | if (file.isHidden()) { | ||
+ | System.out.println("ocult"); | ||
+ | } | ||
+ | |||
+ | File dir = new File("directori"); | ||
+ | if (dir.exists()) { | ||
+ | System.out.println("el directori existeix"); | ||
+ | } else { | ||
+ | System.out.println("el directori NO existeix, el creem"); | ||
+ | dir.mkdir(); | ||
+ | } | ||
+ | if (dir.isDirectory()) { | ||
+ | System.out.println("directori"); | ||
+ | } | ||
+ | |||
+ | String[] fitxers = dir.list(); | ||
+ | for (int i = 0; i < fitxers.length; i++) { | ||
+ | System.out.println("fitxer " + fitxers[i]); | ||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | ==== Classe RandomAccessFile ==== | ||
+ | |||
+ | {{ Pendent }} | ||
+ | |||
+ | === Emmagatzematge d'objectes === | ||
+ | |||
+ | En una primera aproximació a la persistència, es poden fer servir fitxers per emmagatzemar els objectes d'un sistema informàtic. | ||
+ | |||
+ | Existeixen dues possibilitats raonables: | ||
+ | * Serialització i emmagatzematge (dades en binari) | ||
+ | * Emmagatzematge estructurat, per exemple XML, dades tipus text | ||
+ | |||
+ | |||
+ | ==== XML ==== | ||
+ | |||
+ | Java proporciona dues classes que permeten transformar directament objectes a fitxers XML i després recuperar-los novament | ||
+ | |||
+ | * <code class='java'>XMLEncoder</code> | ||
+ | * <code class='java'>XMLDecoder</code> | ||
+ | |||
+ | |||
+ | Cal que les classes siguin del tipus '''JavaBeans''', que vol dir que han de complir els següents requeriments: | ||
+ | |||
+ | * Les classes han de ser serializables (Implementar la interfície '''Serializable''') | ||
+ | * Cal un '''constructor públic sense paràmetres''' | ||
+ | * Tots els atributs d'instància (no estàtics) han de disposar de '''getter/setter''' | ||
+ | |||
+ | [[https://en.wikipedia.org/wiki/JavaBeans https://en.wikipedia.org/wiki/JavaBeans]] | ||
+ | |||
+ | [[https://www.oracle.com/technical-resources/articles/java/persistence4.html https://www.oracle.com/technical-resources/articles/java/persistence4.html]] | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='java'> | ||
+ | public class Cercle implements Serializable { | ||
+ | private Punt centre; | ||
+ | private int radi; | ||
+ | |||
+ | public Cercle() { } | ||
+ | |||
+ | public Cercle(Punt centre, int radi) { | ||
+ | this.centre = centre; | ||
+ | this.radi = radi; | ||
+ | } | ||
+ | |||
+ | public Punt getCentre() { | ||
+ | return centre; | ||
+ | } | ||
+ | public void setCentre(Punt centre) { | ||
+ | this.centre = centre; | ||
+ | } | ||
+ | public int getRadi() { | ||
+ | return radi; | ||
+ | } | ||
+ | public void setRadi(int radi) { | ||
+ | this.radi = radi; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public class Punt implements Serializable { | ||
+ | private int x; | ||
+ | private int y; | ||
+ | |||
+ | public Punt() { } | ||
+ | |||
+ | public Punt(int x, int y) { | ||
+ | this.x = x; | ||
+ | this.y = y; | ||
+ | } | ||
+ | |||
+ | public int getX() { | ||
+ | return x; | ||
+ | } | ||
+ | public void setX(int x) { | ||
+ | this.x = x; | ||
+ | } | ||
+ | public int getY() { | ||
+ | return y; | ||
+ | } | ||
+ | public void setY(int y) { | ||
+ | this.y = y; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public class XMLExemple { | ||
+ | public static void main(String[] args) throws FileNotFoundException { | ||
+ | Punt p = new Punt(2,4); | ||
+ | Cercle c = new Cercle(p, 10); | ||
+ | |||
+ | // Serialització | ||
+ | XMLEncoder e; | ||
+ | e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("cercle3.xml"))); | ||
+ | e.writeObject(c); | ||
+ | e.close(); | ||
+ | |||
+ | // Recuperació | ||
+ | XMLDecoder d = new XMLDecoder(new BufferedInputStream(new FileInputStream("cercle3.xml"))); | ||
+ | Cercle cxml = (Cercle) d.readObject(); | ||
+ | d.close(); | ||
+ | |||
+ | System.out.println("Cercle radi " + cxml.getRadi()); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | <html> | ||
+ | <pre> | ||
+ | <code class='xml'> | ||
+ | <?xml version="1.0" encoding="UTF-8"?> | ||
+ | <java version="1.6.0_24" class="java.beans.XMLDecoder"> | ||
+ | <object class="dam.m3.uf4.Cercle"> | ||
+ | <void property="centre"> | ||
+ | <object class="dam.m3.uf4.Punt"> | ||
+ | <void property="x"> | ||
+ | <int>2</int> | ||
+ | </void> | ||
+ | <void property="y"> | ||
+ | <int>4</int> | ||
+ | </void> | ||
+ | </object> | ||
+ | </void> | ||
+ | <void property="radi"> | ||
+ | <int>10</int> | ||
+ | </void> | ||
+ | </object> | ||
+ | </java> | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> | ||
+ | |||
+ | ==== Serialització ==== | ||
+ | |||
+ | El procés de serialització consisteix en convertir les dades i els objectes en dades binàries, mantenint-ne la estructura. | ||
+ | |||
+ | Es poden serialitzar '''dades primitives''' i '''objectes''' complexes. | ||
+ | |||
+ | Per a serialitzar objectes cal que aquests implementin la interface <code class='java>Serializable</code> (No cal que siguin JavaBeans) | ||
+ | |||
+ | Cal tenir en compte que la informació es recupera en el mateix ordre que s'escriu. | ||
+ | |||
− | + | <html> | |
+ | <pre> | ||
+ | <code class='java'> | ||
+ | public class Punt implements Serializable { | ||
+ | ... | ||
+ | } | ||
− | + | public class Cercle implements Serializable { | |
+ | ... | ||
+ | } | ||
− | + | public class SerializableExemple { | |
− | + | public static void main(String[] args) throws IOException, ClassNotFoundException { | |
+ | Punt p = new Punt(2,4); | ||
+ | Cercle c1 = new Cercle(p, 10); | ||
+ | Cercle c2 = new Cercle(p, 12); | ||
+ | |||
+ | // Serialització | ||
+ | ObjectOutputStream fileOut = new ObjectOutputStream(new FileOutputStream("fitxer.bin")); | ||
+ | fileOut.writeObject("hola que tal"); | ||
+ | fileOut.writeObject(c1); | ||
+ | fileOut.writeObject(c2); | ||
+ | fileOut.close(); | ||
+ | |||
+ | // Recuperació | ||
+ | ObjectInputStream fileIn = new ObjectInputStream(new FileInputStream("fitxer.bin")); | ||
+ | System.out.println((String) fileIn.readObject()); | ||
+ | |||
+ | try { | ||
+ | while (true) { | ||
+ | Cercle aux = (Cercle) fileIn.readObject(); | ||
+ | System.out.println("Cercle radi " + aux.getRadi()); | ||
+ | } | ||
+ | } catch (EOFException e) { | ||
+ | fileIn.close(); | ||
+ | } catch (Exception e) { | ||
+ | if (fileIn != null) fileIn.close(); | ||
+ | System.out.println("Error"); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | </pre> | ||
+ | </html> |
Revisió de 18:04, 17 gen 2022
torna M3 - Programació
Contingut
Lectura i escriptura
Hi ha múltiples ocasions on cal introduir dades a un programa o mostra-les a la sortida, per exemple:
- Línia de comandes
- Formulari amb elements gràfics
- Fitxers
- Pipes o sockets
Java tracta la entrada i sortida d'informació establint uns corrents o fluxes (stream), a través dels quals trasllada blocs de dades (buffer).
Aquests fluxes sempre són binaris evidentment, però Java ofereix dos possibles tractaments:
- Fluxe binari (bytes), classes
InputStream
,OutputStream
- Fluxe de caràcters , classes
Reader
,Writer
Mètodes bàsics
A través de la entrada i sortida estàndard
-
System.in
, és un fluxe binari (InputStream
), que recull les dades entrades per consola -
System.out
, és un fluxe binari (OutputStream
->PrintStream
) amb algunes funcionalitats de tractament, converteix caràcters a bytes segons codificació de la plataforma.
La classe Scanner
La classe Scanner
és una funció d'utilitat simple per a la lectura de dades tipus primitius (int, String
, etc...) o qualsevol objecte que implementi Readable
.
Trenca la lectura segons el delimitador (Per defecte un espai en blanc, encara que es pot modificar)
Scanner scanner = new Scanner(System.in);
System.out.print("Escriu un text: ");
String dada = scanner.next();
System.out.println("Has escrit: " + dada);
scanner.close();
A més implementa la interface Iterator
de manera que permet gestionar la lectura amb les operacions de control dels iteradors
-
hasNext()
-
next()
do {
System.out.print("Escriu \"Fi\" per acabar: ");
dada = scanner.next();
} while (!dada.equals("Fi"));
També permet definir diferents tipus d'entrada com fitxers o cadenes de text, i té mètodes específics per a la lectura d'enters, decimals, etc...
Scanner scanner = new Scanner(System.in);
String dada = "aaa bbb ccc ddd";
do {
dada = scanner.next();
System.out.println( "Conté: " + dada);
} while (scanner.hasNext());
dada = "1 2 3 4";
do {
System.out.println( "Conté: " + scanner.nextInt());
} while (scanner.hasNextInt());
scanner.close();
Readers / Writers
A part dels sistemes anteriors, Java proporciona una capa d'utilitats entre la entrada i l'usuari que permet fer un tractament semblant independentment del tipus d'entrada o sortida que es faci servir.
Les classes utilitzades per al tractament de fluxes de caràcters hereten de java.io.Reader
i de java.io.Writer
Exemple lectura de consola, obliga a gestionar les excepcions
public static void main(String[] args) throws IOException {
InputStreamReader isReader = new InputStreamReader(System.in); // Entrada estandard
BufferedReader bReader = new BufferedReader(isReader); // Buffer
String text = bReader.readLine(); // Lectura d'una linia, String
int num = Integer.parseInt(bReader.readLine()); // Lectura d'una linia i conversió a enter
...
bReader.close();
}
Exemple entrada de fitxers, observar que també usa la classe BufferedReader, una vegada inicialitzat aquest el tractament és independent del tipus d'entrada.
File fitxer = new File("nom"); // Adreçament relatiu
FileReader fReader = null; // Lector del fitxer
BufferedReader bReader = null; // Buffer
String linea;
try {
fReader = new FileReader(fitxer); // Inicialitza lector amb el fitxer a llegir
bReader = new BufferedReader(fReader); // Inicialitza buffer amb el lector (entrada)
while ((linea = bReader.readLine()) != null) {
System.out.println(linea);
}
} catch (FileNotFoundException e) {
System.out.println("Fitxer no existeix");
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
if (bReader != null) {
bReader.close();
}
}
Exemple escriptura a fitxer
boolean append = true;
FileWriter fWriter = new FileWriter("nom", append);
boolean autoFlush=true;
PrintWriter pWriter = new PrintWriter(fWriter, autoFlush);
try {
int i = 0;
while (i < 10) {
pWriter.println("linia " + i++);
}
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
pWriter.close();
}
Fitxers
Els fitxers permeten emmagatzemar dades, aquestes dades poden ser de dos tipus:
- Text, dades alfanumèriques
- Binari, dades en binari
Modes d'accés. Accés aleatori
L'accés a les dades dels fitxers es pot fer de dues maneres
- Seqüencialment, s'obre el fitxer i es llegeix les dades des de l'inici. Aquest tipus de fitxers no tenen cap estructura especial.
Java proporciona la classe File
per a l'accés seqüencial. Les dades poden ser tant text com binàries. Aquesta classe representa directament els objectes del sistema de fitxers i les seves propietats.
- De forma aleatòria, s'obre el fitxer i s'accedeix a una dada concreta. Per a permetre aquest tipus d'accés cal definir certes estructures especials on desar els apuntadors (índexs, file pointers).
Java proporciona la classe RandomAccessFile
per a l'accés aleatori, els fitxers són binaris i tenen un índex que permet accedir a posicions concretes. Aquesta classe és una abstracció més allunyada que File
dels objectes del sistema de fitxers, doncs incorpora estructures pròpies que gestiona Java.
Classe File
La classe File
permet treballar amb fitxers i directoris.
File file = new File("fitxer");
if (file.exists()) {
System.out.println("el fitxer existeix");
} else {
System.out.println("el fitxer NO existeix, el creem");
file.createNewFile();
}
System.out.println("path: " + file.getPath()); // fitxer
System.out.println("path absolut: " + file.getAbsolutePath()); // {path_to_file}/fitxer
System.out.println("ultima modificació : " + new Date(file.lastModified()));
System.out.println("longitud : " + file.length());
file.setExecutable(true);
if (file.canExecute()) {
System.out.println("execució");
}
if (file.canRead()) {
System.out.println("lectura");
}
if (file.canWrite()) {
System.out.println("escriptura");
}
if (file.isFile()) {
System.out.println("fitxer");
}
if (file.isDirectory()) {
System.out.println("directori");
}
if (file.isHidden()) {
System.out.println("ocult");
}
File dir = new File("directori");
if (dir.exists()) {
System.out.println("el directori existeix");
} else {
System.out.println("el directori NO existeix, el creem");
dir.mkdir();
}
if (dir.isDirectory()) {
System.out.println("directori");
}
String[] fitxers = dir.list();
for (int i = 0; i < fitxers.length; i++) {
System.out.println("fitxer " + fitxers[i]);
}
Classe RandomAccessFile
Emmagatzematge d'objectes
En una primera aproximació a la persistència, es poden fer servir fitxers per emmagatzemar els objectes d'un sistema informàtic.
Existeixen dues possibilitats raonables:
- Serialització i emmagatzematge (dades en binari)
- Emmagatzematge estructurat, per exemple XML, dades tipus text
XML
Java proporciona dues classes que permeten transformar directament objectes a fitxers XML i després recuperar-los novament
-
XMLEncoder
-
XMLDecoder
Cal que les classes siguin del tipus JavaBeans, que vol dir que han de complir els següents requeriments:
- Les classes han de ser serializables (Implementar la interfície Serializable)
- Cal un constructor públic sense paràmetres
- Tots els atributs d'instància (no estàtics) han de disposar de getter/setter
[https://en.wikipedia.org/wiki/JavaBeans]
[https://www.oracle.com/technical-resources/articles/java/persistence4.html]
public class Cercle implements Serializable {
private Punt centre;
private int radi;
public Cercle() { }
public Cercle(Punt centre, int radi) {
this.centre = centre;
this.radi = radi;
}
public Punt getCentre() {
return centre;
}
public void setCentre(Punt centre) {
this.centre = centre;
}
public int getRadi() {
return radi;
}
public void setRadi(int radi) {
this.radi = radi;
}
}
public class Punt implements Serializable {
private int x;
private int y;
public Punt() { }
public Punt(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
public class XMLExemple {
public static void main(String[] args) throws FileNotFoundException {
Punt p = new Punt(2,4);
Cercle c = new Cercle(p, 10);
// Serialització
XMLEncoder e;
e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("cercle3.xml")));
e.writeObject(c);
e.close();
// Recuperació
XMLDecoder d = new XMLDecoder(new BufferedInputStream(new FileInputStream("cercle3.xml")));
Cercle cxml = (Cercle) d.readObject();
d.close();
System.out.println("Cercle radi " + cxml.getRadi());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
<object class="dam.m3.uf4.Cercle">
<void property="centre">
<object class="dam.m3.uf4.Punt">
<void property="x">
<int>2</int>
</void>
<void property="y">
<int>4</int>
</void>
</object>
</void>
<void property="radi">
<int>10</int>
</void>
</object>
</java>
Serialització
El procés de serialització consisteix en convertir les dades i els objectes en dades binàries, mantenint-ne la estructura.
Es poden serialitzar dades primitives i objectes complexes.
Per a serialitzar objectes cal que aquests implementin la interface Serializable
(No cal que siguin JavaBeans)
Cal tenir en compte que la informació es recupera en el mateix ordre que s'escriu.
public class Punt implements Serializable {
...
}
public class Cercle implements Serializable {
...
}
public class SerializableExemple {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Punt p = new Punt(2,4);
Cercle c1 = new Cercle(p, 10);
Cercle c2 = new Cercle(p, 12);
// Serialització
ObjectOutputStream fileOut = new ObjectOutputStream(new FileOutputStream("fitxer.bin"));
fileOut.writeObject("hola que tal");
fileOut.writeObject(c1);
fileOut.writeObject(c2);
fileOut.close();
// Recuperació
ObjectInputStream fileIn = new ObjectInputStream(new FileInputStream("fitxer.bin"));
System.out.println((String) fileIn.readObject());
try {
while (true) {
Cercle aux = (Cercle) fileIn.readObject();
System.out.println("Cercle radi " + aux.getRadi());
}
} catch (EOFException e) {
fileIn.close();
} catch (Exception e) {
if (fileIn != null) fileIn.close();
System.out.println("Error");
}
}
}