Diferència entre revisions de la pàgina «M3 - Programació estructurada / Continguts UF3: Fitxers de text»

De wikiserver
Dreceres ràpides: navegació, cerca
(Creació d’un arxiu de text d’accés seqüencial)
(Arxius de text seqüencials)
 
(16 revisions intermèdies per 2 usuaris que no es mostren)
Línia 2: Línia 2:
 
===Creació d’un arxiu de text d’accés seqüencial===
 
===Creació d’un arxiu de text d’accés seqüencial===
  
El programa següent crea un arxiu simple d'accés seqüencial, que podria utilitzar-se en un sistema de comptes per cobrar per ajudar a administrar els diners que deuen a una companyia els clients a crèdit. Per cada client, el programa obté un número de compte, el nom del client i el seu saldo (és a dir, la suma que el client encara deu a la companyia pels béns i serveis rebuts). Les dades
+
Exemple: arxiu de comptes pendents de cobrament.
obtingudes per a cada client constitueixen un “registre” per a aquest client. El número de compte s'utilitza com la clau de registre en aquesta aplicació; l'arxiu es crearà i mantindrà en ordre basat en el número de compte. El programa suposa que l'usuari introdueix els registres en ordre de número de compte.
+
 
 +
El programa suposa que l'usuari introdueix els registres en ordre de número de compte.
 +
 
 +
'''Formatter'''
 +
 
 +
:*Objecte que permet enviar dades a diverses ubicacions, com la pantalla o a un arxiu.
 +
 
 +
:*Es crea amb la ruta del arxiu.
 +
<pre>
 +
sortida = new Formatter("clients.txt");
 +
</pre>
 +
 
 +
'''Consideracions:'''
 +
 
 +
:*Per defecte els arxius es troben en el directori des del qual es va executar el programa.
 +
:*Si l'arxiu no existeix, es crearà.
 +
:*Si s'obre un arxiu existent, el seu contingut es sobrescriu. En aquest punt, l'arxiu s'obre per a escriptura i l'objecte Formatter resultant es pot utilitzar per escriure dades en l'arxiu.
 +
 
 +
'''Mètode format'''
 +
 
 +
:*Pot efectuar un format idèntic al del mètode '''System.out.printf'''.
 +
:*Envia una cadena amb format a la destinació de sortida de l'objecte Formatter
 +
:*La cadena de format "%d %s %s %.2f" indica que el registre actual s'emmagatzemarà com un enter (el número de compte) seguit d'una cadena (el primer nom), una altra cadena (el cognom) i un valor real (el saldo).
 +
:*Cada peça d'informació se separa de la següent, mitjançant un espai.
 +
:*El valor del tipus double (el saldo) s'imprimeix amb dos dígits a la dreta del punt decimal.
 +
:*Les dades en l'arxiu de text es poden veure amb un editor, o posteriorment mitjançant un programa dissenyat per llegir l'arxiu.
 +
 
 +
'''Mètode close'''
 +
 
 +
:*Tanca l'objecte Formatter i l'arxiu de sortida subjacent.
 +
:*Si el mètode '''close''' no es crida en forma explícita, el sistema operatiu normalment tanca l'arxiu quan el programa acaba d'executar-se.
  
La classe Compte guarda la informació de registre del client:
 
 
<pre>
 
<pre>
   public class Compte {
+
Per provar l'exemple, creeu la carpeta FitxersText dins la carpeta NetBeansProjects
     int compte;
+
</pre>
     String nom;
+
 
     String cognom;
+
<source lang="java">
    double saldo;
+
package provacreararxiutext;
 +
 
 +
import java.io.FileNotFoundException;
 +
import java.util.Formatter;
 +
import java.util.Scanner;
 +
 
 +
   public class CrearArxiuText {
 +
 
 +
     private Formatter sortida;
 +
 
 +
    public void obrirArxiu() throws FileNotFoundException {
 +
      
 +
      sortida = new Formatter("../FitxersText/clients.txt");
 +
     }
 +
 
 +
    public void agregarRegistres() {
 +
     
 +
      String cognom, nom;
 +
      double saldo;
 +
      int compte = 1;
 +
      Scanner entrada = new Scanner(System.in);
 +
      System.out.println("Per finalitzar l'entrada, escriu un número de compte negatiu");
 +
      System.out.println("Escriu el numero de compte (> 0), nom, cognom i saldo.");
 +
      while (compte > 0 && entrada.hasNextInt()) {
 +
        compte = entrada.nextInt();
 +
        if (compte > 0) {
 +
          nom = entrada.next();
 +
          cognom = entrada.next();
 +
          saldo = entrada.nextDouble();
 +
          sortida.format("%d %s %s %.2f\n", compte, nom, cognom, saldo);
 +
          System.out.println("Escriu el numero de compte (> 0), nom, cognom i saldo.");
 +
        }
 +
      }
 +
    }
 +
 
 +
    public void tancarArxiu() {
 +
 
 +
      if (sortida != null) {
 +
        sortida.close();
 +
      }
 +
    }
 
   }
 
   }
 +
 +
----
 +
 +
package provacreararxiutext;
 +
import java.io.FileNotFoundException;
 +
 +
  public class ProvaCrearArxiuText {
 +
 +
    public static void main(String args[]) throws FileNotFoundException {
 +
 +
      CrearArxiuText aplicacio = new CrearArxiuText();
 +
      aplicacio.obrirArxiu();
 +
      aplicacio.agregarRegistres();
 +
      aplicacio.tancarArxiu();
 +
    }
 +
  }
 +
</source>
 +
 +
La sentència '''throws FileNotFoundException''' que apareix en els dos fitxers anterior, està indicant que es pot produir una excepció de fitxer no trobat. Quan treballem amb fitxers es poden produir diferents tipus d'excepcions (fitxer no trobat, falta de permisos, etc) que fa que el programa no funcioni amb normalitat. És responsabilitat del programador gestionar aquestes excepcions. Aquí no ho estem fent ja que el tema de control d'excepcions es veu més endavant, però cal tenir clar que la forma com es presenta el codi en aquests exemples '''NO''' és la forma correcta de fer-ho.
 +
 +
===Lectura de dades d’un arxiu de text seqüencial===
 +
 +
:*Objecte '''Scanner:''' per obtenir les dades d'entrada de l'arxiu.
 +
:*Obrir arxiu en mode lectura. Passem un objecte File al constructor que especifica des d'on es llegiran les dades.
 +
<pre>
 +
entrada = new Scanner(new File("clients.txt"))
 
</pre>
 
</pre>
 +
:*Si no troba l'arxiu es provoca una excepció.
 +
:*Lectura fins a fi d'arxiu (el mètode '''hasNext''' retornarà fals)
 +
:*Cada registre és una línia de dades.
 +
 +
<source lang="java">
 +
package provallegirarxiutext;
 +
 +
import java.io.File;
 +
import java.io.FileNotFoundException;
 +
import java.util.Scanner;
 +
 +
  public class LlegirArxiuText {
 +
 +
    private Scanner entrada;
 +
 +
    public void obrirArxiu() throws FileNotFoundException {
 +
 +
      entrada = new Scanner(new File("../FitxersText/clients.txt"));
 +
    }
 +
 +
    public void llegirRegistres() {
  
Ara examinarem la classe CrearArxiuText (codi següent). Es declara la variable '''Formatter''' anomenada sortida. Un objecte '''Formatter''' pot enviar dades a diverses ubicacions, com la pantalla o a un arxiu, com ho fem aquí. L'objecte Formatter s'instancia en el mètode obrirArxiu. Per a crear-lo s'utilitza un objecte String que conté el nom de l'arxiu, incloent la seva ruta. Si no s’especifica una ruta, com es dóna aquí el cas, s’assumeix que els arxius estan en el directori des del qual es va executar el programa. Si l'arxiu no existeix, es crearà. Si s'obre un arxiu existent, el seu contingut es sobrescriu. En aquest punt, l'arxiu s'obre per a escriptura i l'objecte Formatter resultant es pot utilitzar per escriure dades en l'arxiu.
+
      System.out.printf("%-9s%-15s%-18s%10s\n","Compte","Nom","Cognom","Saldo");
 +
      while (entrada.hasNext()) {
 +
        int compte = entrada.nextInt();
 +
        String nom = entrada.next();
 +
        String cognom = entrada.next();
 +
        double saldo = entrada.nextDouble();
 +
        System.out.printf("%-9d%-15s%-18s%10.2f\n",compte, nom, cognom, saldo);
 +
      }
 +
    }
  
El mètode agregarRegistres demana a l'usuari que introdueixi els diversos camps per a cada registre. Si el número de compte és positiu s'escriu a '''clients.txt''' mitjançant el mètode '''format'''. Aquest mètode pot efectuar un format idèntic al del mètode '''System.out.printf''', que es va utilitzar en molts dels exemples de temes anteriors. Aquest mètode envia una cadena amb format a la destinació de sortida de l'objecte Formatter, en aquest cas l'arxiu clients.txt. La cadena de format "%d %s %s %.2f" indica que el registre actual s'emmagatzemarà com un enter (el número de compte) seguit d'una cadena (el primer nom), una altra cadena (el cognom) i un valor real (el saldo). Cada peça d'informació se separa de la següent, mitjançant un espai, i el valor tipus double (el saldo) s'imprimeix amb dos dígits a la dreta del punt decimal. Les dades en l'arxiu de text es poden veure amb un editor, o posteriorment mitjançant un programa dissenyat per llegir l'arxiu.
+
    public void tancarArxiu() {
  
En el mètode tancarArxiu es tanca l'objecte Formatter i l'arxiu de sortida subjacent, mitjançant una crida al mètode '''close'''. Si el mètode '''close''' no es crida en forma explícita, el sistema operatiu normalment tanca l'arxiu quan el programa acaba d'executar-se.
+
      if (entrada != null) {
 +
        entrada.close();
 +
      }
 +
    }
 +
  }
 +
----
 +
package provallegirarxiutext;
  
===Lectura de dades d’un arxiu de text seqüencial===
+
import java.io.FileNotFoundException;
 +
 
 +
  public class ProvaLLegirArxiuText {
 +
 
 +
 
 +
  public static void main(String[] args) throws FileNotFoundException {
 +
 
 +
      LlegirArxiuText l= new LlegirArxiuText();
 +
      l.obrirArxiu();
 +
      l.llegirRegistres();
 +
      l.tancarArxiu();
 +
    }
 +
  }
 +
</source>

Revisió de 15:01, 5 maig 2022

Arxius de text seqüencials

Creació d’un arxiu de text d’accés seqüencial

Exemple: arxiu de comptes pendents de cobrament.

El programa suposa que l'usuari introdueix els registres en ordre de número de compte.

Formatter

  • Objecte que permet enviar dades a diverses ubicacions, com la pantalla o a un arxiu.
  • Es crea amb la ruta del arxiu.
sortida = new Formatter("clients.txt"); 

Consideracions:

  • Per defecte els arxius es troben en el directori des del qual es va executar el programa.
  • Si l'arxiu no existeix, es crearà.
  • Si s'obre un arxiu existent, el seu contingut es sobrescriu. En aquest punt, l'arxiu s'obre per a escriptura i l'objecte Formatter resultant es pot utilitzar per escriure dades en l'arxiu.

Mètode format

  • Pot efectuar un format idèntic al del mètode System.out.printf.
  • Envia una cadena amb format a la destinació de sortida de l'objecte Formatter
  • La cadena de format "%d %s %s %.2f" indica que el registre actual s'emmagatzemarà com un enter (el número de compte) seguit d'una cadena (el primer nom), una altra cadena (el cognom) i un valor real (el saldo).
  • Cada peça d'informació se separa de la següent, mitjançant un espai.
  • El valor del tipus double (el saldo) s'imprimeix amb dos dígits a la dreta del punt decimal.
  • Les dades en l'arxiu de text es poden veure amb un editor, o posteriorment mitjançant un programa dissenyat per llegir l'arxiu.

Mètode close

  • Tanca l'objecte Formatter i l'arxiu de sortida subjacent.
  • Si el mètode close no es crida en forma explícita, el sistema operatiu normalment tanca l'arxiu quan el programa acaba d'executar-se.
Per provar l'exemple, creeu la carpeta FitxersText dins la carpeta NetBeansProjects
package provacreararxiutext;

import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.Scanner;

   public class CrearArxiuText {

     private Formatter sortida;

     public void obrirArxiu() throws FileNotFoundException {
     
       sortida = new Formatter("../FitxersText/clients.txt");
     }

     public void agregarRegistres() {
       
       String cognom, nom;
       double saldo;
       int compte = 1;
       Scanner entrada = new Scanner(System.in);
       System.out.println("Per finalitzar l'entrada, escriu un número de compte negatiu");
       System.out.println("Escriu el numero de compte (> 0), nom, cognom i saldo.");
       while (compte > 0 && entrada.hasNextInt()) {
         compte = entrada.nextInt();
         if (compte > 0) {
           nom = entrada.next();
           cognom = entrada.next();
           saldo = entrada.nextDouble();
           sortida.format("%d %s %s %.2f\n", compte, nom, cognom, saldo);
           System.out.println("Escriu el numero de compte (> 0), nom, cognom i saldo.");
         }
       }
     }

     public void tancarArxiu() {

       if (sortida != null) {
         sortida.close();
       }
     }
   }

----

package provacreararxiutext;
import java.io.FileNotFoundException;

   public class ProvaCrearArxiuText {
 
     public static void main(String args[]) throws FileNotFoundException {

       CrearArxiuText aplicacio = new CrearArxiuText();
       aplicacio.obrirArxiu();
       aplicacio.agregarRegistres();
       aplicacio.tancarArxiu();
     }
   }

La sentència throws FileNotFoundException que apareix en els dos fitxers anterior, està indicant que es pot produir una excepció de fitxer no trobat. Quan treballem amb fitxers es poden produir diferents tipus d'excepcions (fitxer no trobat, falta de permisos, etc) que fa que el programa no funcioni amb normalitat. És responsabilitat del programador gestionar aquestes excepcions. Aquí no ho estem fent ja que el tema de control d'excepcions es veu més endavant, però cal tenir clar que la forma com es presenta el codi en aquests exemples NO és la forma correcta de fer-ho.

Lectura de dades d’un arxiu de text seqüencial

  • Objecte Scanner: per obtenir les dades d'entrada de l'arxiu.
  • Obrir arxiu en mode lectura. Passem un objecte File al constructor que especifica des d'on es llegiran les dades.
entrada = new Scanner(new File("clients.txt"))
  • Si no troba l'arxiu es provoca una excepció.
  • Lectura fins a fi d'arxiu (el mètode hasNext retornarà fals)
  • Cada registre és una línia de dades.
package provallegirarxiutext;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

   public class LlegirArxiuText {

     private Scanner entrada;

     public void obrirArxiu() throws FileNotFoundException {

       entrada = new Scanner(new File("../FitxersText/clients.txt"));
     }

     public void llegirRegistres() {

       System.out.printf("%-9s%-15s%-18s%10s\n","Compte","Nom","Cognom","Saldo");
       while (entrada.hasNext()) {
         int compte = entrada.nextInt();
         String nom = entrada.next();
         String cognom = entrada.next();
         double saldo = entrada.nextDouble();
         System.out.printf("%-9d%-15s%-18s%10.2f\n",compte, nom, cognom, saldo);
       }
     }

     public void tancarArxiu() {

       if (entrada != null) {
         entrada.close();
       }
     }
   }
----
package provallegirarxiutext;

import java.io.FileNotFoundException;

   public class ProvaLLegirArxiuText {


   public static void main(String[] args) throws FileNotFoundException {

       LlegirArxiuText l= new LlegirArxiuText();
       l.obrirArxiu();
       l.llegirRegistres();
       l.tancarArxiu();
     }
   }