Activitats

Completar el codi

L’objectiu d’aquesta activitat és repassar com inicialitzar i usar les diferents classes associades a fluxos d’entrada/sortida al java.

Corregiu el fragments de codi següents afegint una sola línia, o completant-la, on apareix ???:

1.

  1. OutputStream os = obtenirFluxSortida();
  2. BufferedWriter bw = ???;
  3. bw.write(“Escric un String.”,0,17);

2.

  1. File f = new File(ruta);
  2. byte[] buffer = new byte[1024];
  3. ???
  4. bis.read(buffer);
  5. bis.reset(); //Es torna a començar

3.

  1. public class Tupla implements Serializable {
  2. ??? atribut1;
  3. private String atribut2;
  4.  
  5. public Tupla (String i, String j) {
  6. atribut1 = i;
  7. atribut2 = j;
  8. }
  9.  
  10. public String toString() {
  11. return atribut1 +:+ atribut2;
  12. }
  13. }
  14. File f = new File(ruta);
  15. Tupla t1 = new Tupla(100,200);
  16. oos.writeObject(t);
  17. ???
  18. Tupla t2 = (Tupla)ois.readObject();
  19. ???
  20. System.out.println(t2); //Surt per pantalla “null:200”.

4.

  1. //Es vol omplir tot el buffer amb dades
  2. InputStream is = new FileInpuStream (ruta);
  3. byte [] buffer = new byte[long];
  4. int len = 0, inici = 0;
  5. do {
  6. len = ???;
  7. inici += len;
  8. } (while inici < buffer.length);

1.

2.

  1. bis.mark(1024); //O qualsevol valor > 1024

3.

  1. private transient String, oos.close(), ois.close()

4.

  1. len = is.read(buffer, inici, buffer.length - inici);

El corrector de termes automàtic

L’objectiu d’aquesta activitat és veure com es processen les dades que provenen de diferents fluxos per assolir una fita concreta.

Dueu a terme una aplicació per reemplaçar les aparicions de certes paraules per altres dins un conjunt de fitxers de text d’entrada, anomenat “Entrada.txt”, d’acord amb una llista predefinida en un fitxer anomenat “Corrector.txt”. En aquest darrer fitxer es desa el conjunt de termes que cal detectar i la nova paraula per la qual s’han de reemplaçar, com parelles de paraules separades per guió (terme-correcció), escrites en diferents línies. L’aplicació ha de llegir els fitxers i processar-los de manera que es generi nova versió, anomenada “Sortida.txt”, en què només apareguin els termes correctes d’acord amb la llista.

Ara bé, cal fer aquesta tasca amb la particularitat que, en tot moment, a memòria només es pot tenir un únic parell terme-traducció del fitxer “Corrector.txt”, i el fitxer de sortida s’ha d’anar generant a mesura que es van fent les traduccions. Mai no es pot disposar a memòria de tot el contingut de qualsevol dels tres fitxers.

Per exemple:

  • Entrada.txt: es desa en la cache.
  • Corrector.txt: cache-cau
  • Sortida.txt: es desa en la cau.

Es deixa total llibertat sobre quina ha de ser la interfície de l’aplicació. Per fer aquest exercici, no cal preocupar-se de detalls com processar els punts a final de frase o els apòstrofs.

Per exemple, a partir dels fitxers Entrada.txt i Corrector.txt:

Aquest algoritme encriptat requereix un tamany de cache massa gran.
algoritme-algorisme
encriptat-xifrat
tamany-mida
cache-cau

La sortida seria: “Aquest algorisme xifrat requereix una mida de cau massa gran.”

Fitxer Corrector.java

  1. import java.io.*;
  2.  
  3. public class Corrector {
  4.  
  5. public static void main (String[] args) {
  6. File entrada = new File ("Entrada.txt");
  7. File corrector = new File ("Corrector.txt");
  8. File sortida = new File ("Sortida.txt");
  9.  
  10. try {
  11. BufferedReader rdEntrada = new BufferedReader(new FileReader(entrada));
  12. PrintWriter prSortida = new PrintWriter(new FileWriter(sortida));
  13.  
  14. String lin = rdEntrada.readLine();
  15. while (lin != null) {
  16. //Separar una línia en paraules
  17. String[] paraules = lin.split(" ");
  18. boolean inici = true;
  19. for (int i = 0; i < paraules.length; i++) {
  20. //veure si cal escriure espai entre paraules.
  21. if (!inici) {
  22. prSortida.print(" ");
  23. }
  24. inici = false;
  25. String res = null;
  26. BufferedReader rdCorrector = new BufferedReader(new FileReader(corrector));
  27. String parell = rdCorrector.readLine();
  28. //Llegir termes correctors un a un i comparar amb la paraula actual.
  29. while (parell != null) {
  30. res = paraules[i];
  31. String[] corr = parell.split("-");
  32. if (corr[0].equalsIgnoreCase(res)) {
  33. res = corr[1];
  34. break;
  35. }
  36. parell = rdCorrector.readLine();
  37. }
  38. prSortida.print(res);
  39. rdCorrector.close();
  40. }
  41. prSortida.println();
  42. lin = rdEntrada.readLine();
  43. }
  44.  
  45. rdEntrada.close();
  46. prSortida.close();
  47. System.out.println("Fitxer de sortida generat.");
  48.  
  49. } catch (Exception ex) {
  50. System.out.println("Error processant fitxers: " + ex);
  51. }
  52. }
  53.  
  54. }

Persistència d'objectes per tipus primitius

L’objectiu d’aquesta activitat és veure com es pot escriure i recuperar, des d’un fitxer, un conjunt de tipus de dades bàsics. Concretament, el contingut d’un objecte sense recórrer al mecanisme de seriació.

Desenvolupeu una aplicació que emmagatzemi, en un fitxer binari, un conjunt d’instàncies de la classe següent i sigui capaç de recuperar-les. Per aconseguir-ho es pot usar lliurement qualsevol tipus de flux. L’única condició és que no es pot usar seriació, els atributs de cada instància s’han d’abocar i recuperar individualment sobre el fitxer.

Figura

Un exemple de solució, usant un programa de prova molt simple, és el que es mostra tot seguit. Cal tenir en compte que per saber quants objectes hi ha en un fixter, cal, o bé usar una marca de fi de fitxer, o bé indicar a priori quants elements hi ha (amb un valor enter). També, per evitar usar realment seriació, cal desar els atributs de tipus String (el nom), com una cadena de bytes. Atès que una cadena de text té mida variable, això vol dir que caldrà desar la mida de cada cadena de text per després poder-la recuperar satisfactòriament.

  1. import java.io.*;
  2.  
  3. public class TipusProducte {
  4. private String nom;
  5. private int codiIdentificador;
  6. private double preu;
  7. private int estoc;
  8. private boolean aLaVenda;
  9.  
  10. public TipusProducte(String n, int ci, double p, int e, boolean av) {
  11. nom = n;
  12. codiIdentificador = ci;
  13. preu = p;
  14. estoc = e;
  15. aLaVenda = av;
  16. }
  17.  
  18. public String toString() {
  19. return nom + " (" + codiIdentificador + "): " + preu + ", " + estoc + ", " + aLaVenda;
  20. }
  21.  
  22. public static void main (String[] args) {
  23. TipusProducte[] prods = {
  24. new TipusProducte("Producte 1", 1, 10.0, 4, true),
  25. new TipusProducte("Producte 2", 2, 15.0, 0, false),
  26. new TipusProducte("Producte 3", 3, 20.5, 15, true),
  27. new TipusProducte("Producte 4", 4, 9.0, 100, true),
  28. new TipusProducte("Producte 5", 5, 32.99, 1, false)
  29. };
  30.  
  31. System.out.println("Productes originals");
  32. for (int i = 0; i < prods.length; i++)
  33. System.out.println(prods[i]);
  34.  
  35. File f = new File ("Fitxer.tp");
  36. //Escriptura
  37. try {
  38. dos.writeInt(prods.length);
  39. for (int i = 0; i < prods.length; i++) {
  40. byte[] b = prods[i].nom.getBytes();
  41. dos.writeInt(b.length);
  42. dos.write(b);
  43. dos.writeInt(prods[i].codiIdentificador);
  44. dos.writeDouble(prods[i].preu);
  45. dos.writeInt(prods[i].estoc);
  46. dos.writeBoolean(prods[i].aLaVenda);
  47. }
  48. dos.close();
  49. System.out.println("Fitxer generat: " + f.getName());
  50. } catch (Exception ex) {
  51. System.out.println("Error desant les dades: " + ex);
  52. f.delete();
  53. }
  54.  
  55. //Lectura
  56. TipusProducte[] llegits = new TipusProducte[prods.length];
  57. if (f.exists()) {
  58. try {
  59. int nprod = dis.readInt();
  60. llegits = new TipusProducte[nprod];
  61. for (int i = 0; i < llegits.length; i++) {
  62. int longNom = dis.readInt();
  63. byte[] b = new byte[longNom];
  64. dis.read(b);
  65. String n = new String(b);
  66. int c = dis.readInt();
  67. double p = dis.readDouble();
  68. int e = dis.readInt();
  69. boolean av = dis.readBoolean();
  70. llegits[i] = new TipusProducte(n, c, p, e, av);
  71. }
  72. dis.close();
  73. System.out.println("Lectura finalitzada: " + f.getName());
  74. } catch (Exception ex) {
  75. System.out.println("Error llegint les dades: " + ex);
  76. }
  77.  
  78. }
  79.  
  80. System.out.println("Productes llegits");
  81. for (int i = 0; i < llegits.length; i++)
  82. System.out.println(llegits[i]);
  83.  
  84. }
  85.  
  86. }

Desar la partida

L’objectiu d’aquesta activitat és entendre com funciona el mecanisme de seriació del Java, de manera que és possible desar i restaurar el Model d’una aplicació de manera relativament simple.

Modifiqueu el codi font d’un joc del Buscamines, disponible al final d’aquest enunciat, de manera que el jugador pugui desar l’estat de la partida i reprendre-la en qualsevol moment. Per fer-ho, useu el mecanisme de seriació per defecte que proporciona el Java.

Codi ( 4.8 KB )

Per afegir aquesta funcionalitat és suficient de fer que tots els elements del programa implementin la interfície Serializable. Llavors, es pot gestionar la càrrega o desat de la partida (atribut “model” a la classe BuscaminesGUI) usant seriació d’objectes. Per exemple, es pot afegir un menú a la finestra per poder dur a terme aquestes accions. Ara bé, cal no oblidar-se, un cop carregat el model, d’actualitzar la interfície d’usuari cridant “actualitzarCasella”.

  1. //Menu carregar/Desar
  2. JMenuBar menu = new JMenuBar();
  3. JMenu estat = new JMenu("Partida");
  4. menu.add(estat);
  5. JMenuItem load = new JMenuItem("Carregar Partida");
  6. estat.add(load);
  7. load.addActionListener(new ActionListener() {
  8. public void actionPerformed(ActionEvent e) {
  9. JFileChooser gestorFitxers = new JFileChooser();
  10. gestorFitxers.showOpenDialog(null);
  11. File f = gestorFitxers.getSelectedFile();
  12. if (f != null) {
  13. try {
  14. model = (Partida)ois.readObject();
  15. ois.close();
  16. //Actualitzar caselles
  17. for(int i = 0;i < caselles.length;i++) {
  18. for (int j = 0; j < caselles[i].length; j++) {
  19. Casella c = caselles[i][j];
  20. actualitzarCasella (c, model.obtenirPosicio(c.x,c.y));
  21. }
  22. }
  23. } catch (Exception ex) {
  24. JOptionPane.showMessageDialog(null,"Error obrint les dades.\n" + ex,"Obrir...",JOptionPane.ERROR_MESSAGE);
  25. }
  26. }
  27. }
  28. });
  29.  
  30. JMenuItem save = new JMenuItem("Desar Partida");
  31. estat.add(save);
  32. save.addActionListener(new ActionListener() {
  33. public void actionPerformed(ActionEvent e) {
  34. JFileChooser gestorFitxers = new JFileChooser();
  35. gestorFitxers.showSaveDialog(null);
  36. File f = gestorFitxers.getSelectedFile();
  37. if (f != null) {
  38. try {
  39. oos.writeObject(model);
  40. oos.close();
  41. } catch (Exception ex) {
  42. JOptionPane.showMessageDialog(null,"Error desant les dades.\n" + ex,"Desar...",JOptionPane.ERROR_MESSAGE);
  43. }
  44. }
  45. }
  46. });
  47.  
  48. this.setJMenuBar(menu);

Anar a la pàgina anterior:
Fluxos i fitxers
Anar a la pàgina següent:
Exercicis