Diferència entre revisions de la pàgina «DAM-M3-UF5. Lectura i escriptura. Fitxers»

De Wiki IES Marianao. Departament Informàtica
Dreceres ràpides: navegació, cerca
(Serialització)
Línia 34: Línia 34:
  
 
Trenca la lectura segons el delimitador (Per defecte un espai en blanc, encara que es pot modificar)
 
Trenca la lectura segons el delimitador (Per defecte un espai en blanc, encara que es pot modificar)
 
+
<html>
 
<pre>
 
<pre>
        Scanner sc = new Scanner( System.in );
+
<code class='java'>
 +
    Scanner sc = new Scanner( System.in );
  
        System.out.print( "Escriu un text: " );
+
    System.out.print( "Escriu un text: " );
        String dada = sc.next();
+
    String dada = sc.next();
        System.out.println( "Has escrit: " + dada);
+
    System.out.println( "Has escrit: " + dada);
 +
</code>
 
</pre>
 
</pre>
 
+
</html>
  
 
A més implementa la interface Iterator de manera que permet gestionar la lectura amb les operacions de control dels iteradors
 
A més implementa la interface Iterator de manera que permet gestionar la lectura amb les operacions de control dels iteradors
Línia 49: Línia 51:
 
* next()
 
* next()
  
 +
<html>
 
<pre>
 
<pre>
        do {
+
<code class='java'>
            System.out.print( "Escriu \"Fi\" per acabar: " );
+
    do {
            dada = sc.next();
+
        System.out.print( "Escriu \"Fi\" per acabar: " );
 +
        dada = sc.next();
 
            
 
            
        } while (!dada.equals("Fi"));
+
    } while (!dada.equals("Fi"));
 +
</code>
 
</pre>
 
</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...
 
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'>
 +
    String dada = "aaa bbb ccc ddd";
 +
    Scanner sc = new Scanner(dada);
 +
 +
    do {
 +
        dada = sc.next();
 +
        System.out.println( "Conté: " + dada);         
 +
    } while (sc.hasNext());
  
<pre>
+
    dada = "1 2 3 4";
        String dada = "aaa bbb ccc ddd";
+
    Scanner sc = new Scanner(dada);
        Scanner sc = new Scanner(dada);
 
        do {
 
            dada = sc.next();
 
            System.out.println( "Conté: " + dada);         
 
        } while (sc.hasNext());
 
  
        dada = "1 2 3 4";
+
    do {
        Scanner sc = new Scanner(dada);
+
        System.out.println( "Conté: " + sc.nextInt());           
        do {
+
    } while (sc.hasNextInt());
            System.out.println( "Conté: " + sc.nextInt());           
+
</code>
        } while (sc.hasNextInt());
 
 
</pre>
 
</pre>
 +
</html>
  
  
Línia 86: Línia 97:
 
'''Exemple lectura de consola''', obliga a gestionar les excepcions
 
'''Exemple lectura de consola''', obliga a gestionar les excepcions
  
 +
<html>
 
<pre>
 
<pre>
 +
<code class='java'>
 
public static void main(String[] args) throws IOException {
 
public static void main(String[] args) throws IOException {
        //primer();
+
    //primer();
  
        InputStreamReader is = new InputStreamReader(System.in);       // Entrada, estandard
+
    InputStreamReader is = new InputStreamReader(System.in); // Entrada, estandard
  
        BufferedReader in = new BufferedReader(is);           // buffer   
+
    BufferedReader in = new BufferedReader(is); // buffer   
  
        String text = in.readLine(); //Lectura String
+
    String text = in.readLine(); //Lectura String
 
        
 
        
        int num = Integer.parseInt(in.readLine()); //Lectura Enter
+
    int num = Integer.parseInt(in.readLine()); //Lectura Enter
        ...
+
    ...
 
}
 
}
 
+
</code>
 
</pre>
 
</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.
 
'''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>
 
<pre>
        File fitxer = new File("nom");   // Adreçament relatiu   
+
<code class='java'>
        FileReader fr = null;       // Entrada
+
    File fitxer = new File("nom"); // Adreçament relatiu   
        BufferedReader br;           // buffer   
+
    FileReader fr = null; // Entrada
        String linea;
+
    BufferedReader br; // buffer   
 +
    String linea;
  
        try {
+
    try {
            fr = new FileReader (fitxer); // Inicialitza entrada del fitxer
+
        fr = new FileReader (fitxer); // Inicialitza entrada del fitxer
            br = new BufferedReader(fr);     // Inicialitza buffer amb l’entrada
+
        br = new BufferedReader(fr); // Inicialitza buffer amb l’entrada
            while((linea=br.readLine())!=null)  {
+
                System.out.println(linea);
+
      while((linea=br.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 (fr != null) fr.close();
 
 
         }
 
         }
 +
    } catch (FileNotFoundException e) {
 +
        System.out.println("Fitxer no existeix");
 +
    } catch (IOException e) {
 +
        System.out.println(e.getMessage());
 +
    } finally {
 +
        if (fr != null) fr.close();
 +
    }
 +
</code>
 
</pre>
 
</pre>
 +
</html>
  
  
 
'''Exemple escriptura a fitxer'''
 
'''Exemple escriptura a fitxer'''
  
 +
<html>
 
<pre>
 
<pre>
        boolean append = true;
+
<code class='java'>
        FileWriter fw = new FileWriter("nom", append);
+
    boolean append = true;
        PrintWriter pw = new PrintWriter(fw, true);
+
    FileWriter fw = new FileWriter("nom", append);
 +
    PrintWriter pw = new PrintWriter(fw, true);
 
          
 
          
        try {
+
    try {
            int i = 0;
+
        int i = 0;
            while (i < 10) {
+
 
                pw.println("linia " + i++);
+
        while (i < 10) {
            }
+
            pw.println("linia " + i++);
        } catch (Exception e) {
 
            System.out.println(e.getMessage());
 
        } finally {
 
            fw.close();
 
 
         }
 
         }
 +
    } catch (Exception e) {
 +
        System.out.println(e.getMessage());
 +
    } finally {
 +
        fw.close();
 +
    }
 +
</code>
 
</pre>
 
</pre>
 +
</html>
  
  
Línia 169: Línia 193:
  
  
 +
<html>
 
<pre>
 
<pre>
        File f = new File("fitxer");
+
<code class='java'>
 +
    File f = new File("fitxer");
 
        
 
        
        if (f.exists()) System.out.println("el fitxer existeix");
+
    if (f.exists()) System.out.println("el fitxer existeix");
        else {
+
    else {
            System.out.println("el fitxer NO existeix, el creem");
+
        System.out.println("el fitxer NO existeix, el creem");
            f.createNewFile();
+
        f.createNewFile();
        }
+
    }
 
        
 
        
        System.out.println("path: " + f.getPath());   // fitxer
+
    System.out.println("path: " + f.getPath()); // fitxer
        System.out.println("path absolut: " + f.getAbsolutePath()); // {path_to_file}/fitxer
+
    System.out.println("path absolut: " + f.getAbsolutePath()); // {path_to_file}/fitxer
        System.out.println("ultima modificació : " + new Date((long)f.lastModified()*1000));
+
    System.out.println("ultima modificació : " + new Date((long)f.lastModified()*1000));
        System.out.println("longitud : " + f.length());
+
    System.out.println("longitud : " + f.length());
 
        
 
        
        f.setExecutable(true);
+
    f.setExecutable(true);
 
        
 
        
        if (f.canExecute()) System.out.println("execució");
+
    if (f.canExecute()) System.out.println("execució");
        if (f.canRead()) System.out.println("lectura");
+
    if (f.canRead()) System.out.println("lectura");
        if (f.canWrite()) System.out.println("escriptura");
+
    if (f.canWrite()) System.out.println("escriptura");
        if (f.isFile()) System.out.println("fitxer");
+
    if (f.isFile()) System.out.println("fitxer");
        if (f.isDirectory()) System.out.println("directori");
+
    if (f.isDirectory()) System.out.println("directori");
        if (f.isHidden()) System.out.println("ocult");
+
    if (f.isHidden()) System.out.println("ocult");
 
        
 
        
        File d = new File("directori");
+
    File d = new File("directori");
        if (d.exists()) System.out.println("el directori existeix");
+
    if (d.exists()) System.out.println("el directori existeix");
        else {
+
    else {
            System.out.println("el directori NO existeix, el creem");
+
        System.out.println("el directori NO existeix, el creem");
            d.mkdir();
+
        d.mkdir();
        }
+
    }
        if (d.isDirectory()) System.out.println("directori");
+
    if (d.isDirectory()) System.out.println("directori");
     
+
     
        String[] fitxers = d.list();
+
    String[] fitxers = d.list();
        for (int i = 0; i < fitxers.length; i++) {
+
    for (int i = 0; i < fitxers.length; i++) {
            System.out.println("fitxer " + fitxers[i]);   
+
        System.out.println("fitxer " + fitxers[i]);   
        }
+
    }
 +
</code>
 
</pre>
 
</pre>
 +
</html>
  
 
==== Classe RandomAccessFile ====
 
==== Classe RandomAccessFile ====
Línia 235: Línia 263:
 
https://www.oracle.com/technetwork/java/persistence4-140124.html  
 
https://www.oracle.com/technetwork/java/persistence4-140124.html  
  
 +
<html>
 
<pre>
 
<pre>
 +
<code class='java'>
 
public class Cercle {
 
public class Cercle {
 
     private Punt centre;
 
     private Punt centre;
Línia 305: Línia 335:
 
     }
 
     }
 
}
 
}
 +
</code>
 +
</pre>
 +
</html>
  
<?xml version="1.0" encoding="UTF-8"?>
+
<html>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
+
<pre>
<object class="dam.m3.uf4.Cercle">
+
<code class='xml'>
  <void property="centre">
+
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  <object class="dam.m3.uf4.Punt">
+
&lt;java version=&quot;1.6.0_24&quot; class=&quot;java.beans.XMLDecoder&quot;&gt;
    <void property="x">
+
    &lt;object class=&quot;dam.m3.uf4.Cercle&quot;&gt;
    <int>2</int>
+
        &lt;void property=&quot;centre&quot;&gt;
    </void>
+
            &lt;object class=&quot;dam.m3.uf4.Punt&quot;&gt;
    <void property="y">
+
                &lt;void property=&quot;x&quot;&gt;
    <int>4</int>
+
                    &lt;int&gt;2&lt;/int&gt;
    </void>
+
                &lt;/void&gt;
  </object>
+
                &lt;void property=&quot;y&quot;&gt;
  </void>
+
                    &lt;int&gt;4&lt;/int&gt;
  <void property="radi">
+
                &lt;/void&gt;
  <int>10</int>
+
            &lt;/object&gt;
  </void>
+
        &lt;/void&gt;
</object>
+
        &lt;void property=&quot;radi&quot;&gt;
</java>
+
            &lt;int&gt;10&lt;/int&gt;
 
+
        &lt;/void&gt;
 +
    &lt;/object&gt;
 +
&lt;/java&gt;
 +
</code>
 
</pre>
 
</pre>
 
+
</html>
 
==== Serialització ====
 
==== Serialització ====
  
Línia 338: Línia 374:
  
  
 +
<html>
 
<pre>
 
<pre>
 
+
<code class='java'>
 
public class Punt implements Serializable {
 
public class Punt implements Serializable {
...
+
    ...
 
}
 
}
  
 
public class Cercle implements Serializable {
 
public class Cercle implements Serializable {
...
+
    ...
 
}
 
}
  
 
public class SerializableExemple {
 
public class SerializableExemple {
 +
 
     public static void main(String[] args) throws IOException, ClassNotFoundException {
 
     public static void main(String[] args) throws IOException, ClassNotFoundException {
 
         Punt p = new Punt(2,4);
 
         Punt p = new Punt(2,4);
Línia 378: Línia 416:
 
     }
 
     }
 
}
 
}
 +
</code>
 
</pre>
 
</pre>
 +
</html>

Revisió del 23:26, 29 gen 2021

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:

  • 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 sc = new Scanner( System.in );

    System.out.print( "Escriu un text: " );
    String dada = sc.next();
    System.out.println( "Has escrit: " + dada);

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 = sc.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...


    String dada = "aaa bbb ccc ddd";
    Scanner sc = new Scanner(dada);

    do {
        dada = sc.next();
        System.out.println( "Conté: " + dada);           
    } while (sc.hasNext());

    dada = "1 2 3 4";
    Scanner sc = new Scanner(dada);

    do {
        System.out.println( "Conté: " + sc.nextInt());           
    } while (sc.hasNextInt());


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 {
    //primer();

    InputStreamReader is = new InputStreamReader(System.in); // Entrada, estandard

    BufferedReader in = new BufferedReader(is); // buffer   

    String text = in.readLine(); //Lectura String
       
    int num = Integer.parseInt(in.readLine()); //Lectura Enter
    ...
}

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 fr = null; // Entrada
    BufferedReader br; // buffer   
    String linea;

    try {
        fr = new FileReader (fitxer); // Inicialitza entrada del fitxer
        br = new BufferedReader(fr); // Inicialitza buffer amb l’entrada
 
       while((linea=br.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 (fr != null) fr.close();
    }


Exemple escriptura a fitxer


    boolean append = true;
    FileWriter fw = new FileWriter("nom", append);
    PrintWriter pw = new PrintWriter(fw, true);
         
    try {
        int i = 0;

        while (i < 10) {
            pw.println("linia " + i++);
        }
    } catch (Exception e) {
        System.out.println(e.getMessage());
    } finally {
        fw.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 f = new File("fitxer");
       
    if (f.exists()) System.out.println("el fitxer existeix");
    else {
        System.out.println("el fitxer NO existeix, el creem");
        f.createNewFile();
    }
       
    System.out.println("path: " + f.getPath()); // fitxer
    System.out.println("path absolut: " + f.getAbsolutePath()); // {path_to_file}/fitxer
    System.out.println("ultima modificació : " + new Date((long)f.lastModified()*1000));
    System.out.println("longitud : " + f.length());
       
    f.setExecutable(true);
       
    if (f.canExecute()) System.out.println("execució");
    if (f.canRead()) System.out.println("lectura");
    if (f.canWrite()) System.out.println("escriptura");
    if (f.isFile()) System.out.println("fitxer");
    if (f.isDirectory()) System.out.println("directori");
    if (f.isHidden()) System.out.println("ocult");
       
    File d = new File("directori");
    if (d.exists()) System.out.println("el directori existeix");
    else {
        System.out.println("el directori NO existeix, el creem");
        d.mkdir();
    }
    if (d.isDirectory()) System.out.println("directori");
      
    String[] fitxers = d.list();
    for (int i = 0; i < fitxers.length; i++) {
        System.out.println("fitxer " + fitxers[i]);   
    }

Classe RandomAccessFile

Plantilla: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

http://java.sun.com/products/jfc/tsc/articles/persistence3/

Cal descartar qualsevol altre solució, com per exemple mapejar els objectes en fitxers amb estructures de files i separant els valors dels atributs per ";" (p.e. format csv).

XML

Java proporciona dues classes que permeten transformar directament objectes a fitxers XML i després recuperar-los novament

  • XMLEncoder
  • XMLDecoder

Aquest mètode només permet treballar amb objectes JavaBeans, aquests compleixen certes restriccions

http://ca.wikipedia.org/wiki/JavaBeans

https://www.oracle.com/technetwork/java/persistence4-140124.html


public class Cercle {
    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 {
    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");
        }
    }
}