Capitolo 14: Flussi Capitolo 14 Flussi ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 1 Capitolo 14: Flussi Figura 1 Una finestra di dialogo di tipo JFileChooser ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 2 Capitolo 14: Flussi Figura 2 Il codice di Cesare ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 3 File Encryptor.java import import import import import import Capitolo 14: Flussi java.io.File; java.io.FileInputStream; java.io.FileOutputStream; java.io.InputStream; java.io.OutputStream; java.io.IOException; /** Un cifratore cifra file usando la crittografia di Cesare. Per la decifrazione, usate un cifratore con la chiave opposta a quella di cifratura. */ public class Encryptor { /** Costruisce un cifratore. @param aKey la chiave di cifratura ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 4 Capitolo 14: Flussi public Encryptor(int aKey) { key = aKey; } /** Cifra il contenuto di un file. @param inFile il file di ingresso @param outFile il file di uscita */ public void encryptFile(File inFile, File outFile) throws IOException { InputStream in = null; OutputStream out = null; ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 5 Capitolo 14: Flussi try { in = new FileInputStream(inFile); out = new FileOutputStream(outFile); encryptStream(in, out); } finally { if (in != null) in.close(); if (out != null) out.close(); } } /** Cifra il contenuto di un flusso. @param in il flusso di ingresso @param out il flusso di uscita */ public void encryptStream(InputStream in, OutputStream out) throws IOException */ ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 6 Capitolo 14: Flussi { boolean done = false; while (!done) { int next = in.read(); if (next == -1) done = true; else { byte b = (byte)next; byte c = encrypt(b); out.write(c); } } } /** Cifra un byte. @param b il byte da cifrare @return il byte cifrato */ ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 7 Capitolo 14: Flussi public byte encrypt(byte b) { return (byte)(b + key); } private int key; } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 8 Capitolo 14: Flussi File EncryptorTest.java import import import import java.io.File; java.io.IOException; javax.swing.JFileChooser; javax.swing.JOptionPane; /** Un programma per collaudare il cifratore con il codice di Cesare. */ public class EncryptorTest { public static void main(String[] args) { try { JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) System.exit(0); ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 9 Capitolo 14: Flussi File inFile = chooser.getSelectedFile(); if (chooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) System.exit(0); File outFile = chooser.getSelectedFile(); String input = JOptionPane.showInputDialog("Key"); int key = Integer.parseInt(input); Encryptor crypt = new Encryptor(key); crypt.encryptFile(inFile, outFile); } catch (NumberFormatException exception) { System.out.println("Key must be an integer: " + exception); } catch (IOException exception) { System.out.println("Error processing file: " + exception); } System.exit(0); } } 10 Capitolo 14: Flussi Figura 3 Crittografia con chiave pubblica ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 11 Capitolo 14: Flussi File Crypt.java import java.io.File; import java.io.IOException; /** Un programma che esegue il cifratore con il codice di Cesare usando gli argomenti forniti sulla riga comandi. */ public class Crypt { public static void main(String[] args) { boolean decrypt = false; int key = DEFAULT_KEY; File inFile = null; File outFile = null; if (args.length < 2 || args.length > 4) usage(); ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 12 Capitolo 14: Flussi try { for (int i = 0; i < args.length; i++) { if (args[i].charAt(0) == '-') { // è un’opzione della riga comandi char option = args[i].charAt(1); if (option == 'd') decrypt = true; else if (option == 'k') key = Integer.parseInt( args[i].substring(2)); } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 13 Capitolo 14: Flussi else { // è il nome di un file if (inFile == null) inFile = new File(args[i]); else if (outFile == null) outFile = new File(args[i]); else usage(); } } if (decrypt) key = -key; Encryptor crypt = new Encryptor(key); crypt.encryptFile(inFile, outFile); } catch (NumberFormatException exception) { System.out.println("Key must be an integer: " + exception); } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 14 Capitolo 14: Flussi catch (IOException exception) { System.out.println("Error processing file: " + exception); } } /** Stampa un messaggio che descrive l’uso corretto, poi termina il programma. */ public static void usage() { System.out.println( "Usage: java Crypt [–d] [–kn] infile outfile"); System.exit(1); } public static final int DEFAULT_KEY = 3; } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 15 Capitolo 14: Flussi File PurseTest.java import java.io.File; import import import import import import java.io.IOException; java.io.FileInputStream; java.io.FileOutputStream; java.io.ObjectInputStream; java.io.ObjectOutputStream; javax.swing.JOptionPane; /** Questo programma verifica la serializzazione di un oggetto di tipo Purse. Se esiste un file con dati serializzati di un borsellino, esso viene caricato; altrimenti il programma parte con un nuovo borsellino. Ulteriori monete vengono aggiunte al borsellino, quindi i dati del borsellino vengono memorizzati. */ ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 16 Capitolo 14: Flussi public class PurseTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Purse myPurse; File f = new File("purse.dat"); if (f.esists()) { ObjectInputStream in = new ObjectInputStream (new FileInputStream(f)); myPurse = (Purse)in.readObject(); in.close(); } else myPurse = new Purse(); ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 17 Capitolo 14: Flussi // aggiungi monete al borsellino myPurse.add(new Coin(NICKEL_VALUE, "nickel")); myPurse.add(new Coin(DIME_VALUE, "dime")); myPurse.add(new Coin(QUARTER_VALUE, "quarter")); double totalValue = myPurse.getTotal(); System.out.println("The total is " + totalValue); ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream(f)); out.writeObject(myPurse); out.close(); } private static final double NICKEL_VALUE = 0.05; private static final double DIME_VALUE = 0.1; private static final double QUARTER_VALUE = 0.25; } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 18 Capitolo 14: Flussi Figura 4 Accesso sequenziale e casuale ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 19 Capitolo 14: Flussi File BankDataTest.java import java.io.IOException; import java.io.RandomAccessFile; import javax.swing.JOptionPane; /** Questo programma collauda l’accesso casuale. Potete accedere a conti esistenti ed aggiungervi gli interessi, oppure creare nuovi conti. I conti vengono memorizzati in un file ad accesso casuale. */ public class BankDataTest { public static void main(String[] args) { BankData data = new BankData(); try ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 20 Capitolo 14: Flussi { data.open("bank.dat"); boolean done = false; while (!done) { String input = JOptionPane.showInputDialog( "Account number or " + data.size() + " for new account"); if (input == null) done = true; else { int pos = Integer.parseInt(input); if (0 <= pos && pos < data.size()) // aggiungi gli interessi ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 21 { Capitolo 14: Flussi SavingsAccount account = data.read(pos); System.out.println("balance=" + account.getBalance() + ",interestRate=" + account.getInterestRate()); account.addInterest(); data.write(pos, account); } else // aggiungi un conto { input = JOptionPane.showInputDialog( "Balance"); double balance = Double.parseDouble(input); input = JOptionPane.showInputDialog( "Interest Rate"); double interestRate = Double.parseDouble(input); ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 22 Capitolo 14: Flussi SavingsAccount account = new SavingsAccount(interestRate); account.deposit(balance); data.write(data.size(), account); } } } } finally { data.close(); System.exit(0); } } } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 23 Capitolo 14: Flussi File BankData.java import java.io.IOException; import java.io.RandomAccessFile; /** Questa classe funge da tramite per un file ad accesso casuale contenente i dati di conti di risparmio. */ public class BankData { /** Costruisce un oggetto di tipo BankData senza associarlo ad un file. */ public BankData() { file = null; } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 24 Capitolo 14: Flussi /** Apre il file dei dati. @param filename il nome del file che contiene informazioni sui conti di risparmio */ public void open(String filename) throws IOException { if (file != null) file.close(); file = new RandomAccessFile(filename, "rw"); } /** Restituisce il numero di conti presenti nel file. @return il numero di conti */ public int size() { return (int)(file.length() / RECORD_SIZE); } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 25 Capitolo 14: Flussi /** Chiude il file dei dati. */ public void close() throws IOException { if (file != null) file.close(); file = null; } /** Legge il record di un @param n l’indice del @return un oggetto di inizializzato */ conto di risparmio. conto nel file dei dati tipo SavingsAccount con i dati letti dal file public SavingsAccount read(int n) throws IOException ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 26 Capitolo 14: Flussi { file.seek(n * RECORD_SIZE); double balance = file.readDouble(); double interestRate = file.readDouble(); SavingsAccount account = new SavingsAccount(interestRate); account.deposit(balance); return account; } /** Scrive il record di un conto di risparmio nel file dei dati. @param n l’indice del conto nel file dei dati @param account il conto da scrivere */ ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 27 Capitolo 14: Flussi public void write(int n, SavingsAccount account) throws IOException { file.seek(n * RECORD_SIZE); file.writeDouble(account.getBalance()); file.writeDouble(account.getInterestRate()); } private RandomAccessFile file; public static final int DOUBLE_SIZE = 8; public static final int RECORD_SIZE = 2 * DOUBLE_SIZE; } ©2002 Apogeo srl Horstmann-Concetti di informatica e fondamenti di Java 2 28