Capitolo 14
Flussi
©2002 Apogeo srl
Horstmann-Concetti di informatica e fondamenti di Java 2 2
Figura 1
Una finestra di dialogo di tipo JFileChooser
Figura 2 Il codice di Cesare
©2002 Apogeo srl
Horstmann-Concetti di informatica e fondamenti di Java 2 4
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
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 6
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
*/
{
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 8
public byte encrypt(byte b) {
return (byte)(b + key);
}
private int key;
}
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);
10
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);
} }
Figura 3 Crittografia con chiave pubblica
©2002 Apogeo srl
Horstmann-Concetti di informatica e fondamenti di Java 2 12
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();
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 14
{
// è 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);
}
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 16
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.
*/
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 18
// 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;
}
Figura 4 Accesso sequenziale e casuale
©2002 Apogeo srl
Horstmann-Concetti di informatica e fondamenti di Java 2 20
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
{
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 22
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);
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 24
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;
}
/**
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 26
/**
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
{
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 28
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;
}