Capitolo 14 Flussi 1
Figura 1 Una finestra di dialogo di tipojfilechooser 2
Figura 2 Il codice di Cesare 3
File Encryptor.java import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.inputstream; import java.io.outputstream; import 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 4
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; 5
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 6
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 7
public byte encrypt(byte b) return (byte)(b + key); private int key; 8
File EncryptorTest.java import java.io.file; import java.io.ioexception; import javax.swing.jfilechooser; import 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); 9
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
Figura 3 Crittografia con chiave pubblica 11
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(); 12
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)); 13
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); 14
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; 15
File PurseTest.java import java.io.file; import java.io.ioexception; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.objectinputstream; import java.io.objectoutputstream; import 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. 16
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(); 17
// 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; 18
Figura 4 Accesso sequenziale e casuale 19
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 20
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 21
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); 22
SavingsAccount account = new SavingsAccount(interestRate); account.deposit(balance); data.write(data.size(), account); finally data.close(); System.exit(0); 23
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; 24
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); 25
Chiude il file dei dati. public void close() throws IOException if (file!= null) file.close(); file = null; Legge il record di un conto di risparmio. @param n l indice del conto nel file dei dati @return un oggetto di tipo SavingsAccount inizializzato con i dati letti dal file public SavingsAccount read(int n) throws IOException 26
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 27
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; 28