Java seisukohalt võib vood jagada:
Faili saab kasutada kui voogu (failivoog) või kui otsepöördusfaili (e. suvapöördusfaili, ingl.k. random access file).
Programmides saab avatud faili kohta informatsiooni edastamiseks kasutada nn. failikirjeldajat (ingl.k. file descriptor), mis viitab failile kohalikus failisüsteemis või pistikule (ingl.k. socket).
FileDescriptor
InputStream
ByteArrayInputStreamOutputStream
FileInputStream
FilterInputStreamBufferedInputStreamPipedInputStream
DataInputStream
StringBufferInputStream
ByteArrayOutputStreamRandomAccessFile
FileOutputStream
FilterOutputStreamBufferedOutputStreamPipedOutputStream
DataOutputStream
PrintStream
Reader
BufferedReaderStreamTokenizer
CharArrayReader
FilterReader
InputStreamReaderFileReaderPipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriterFileWriterPipedWriter
PrintWriter
StringWriter
Standardväljund System.out ja veaväljund System.err kuuluvad klassi PrintStream
Tekstivoogudega (NB! Unicode) tegelevad Reader- ja Writer-klassid, baidivoogudega InputStream- ja OutputStream-klassid, andmevoogudega DataInputStream- ja DataOutputStream-klassid, kusjuures andmevoo interpreteerimiseks võib ise luua uusi mooduseid spetsialiseerides klasse prefiksiga Filter...
Kui voo allikaks on fail, siis kasutatakse "aluspõhjaks" (täpsem info leidub vookonstruktorite kirjeldustes) klasse FileInputStream ja FileOutputStream (andmed) või FileReader ja FileWriter (tekst).
Sisemälu saab kasutada baidivoona (ByteArrayOutputStream, ByteArrayInputStream) või tekstivoona (CharArrayWriter, StringWriter, CharArrayReader, StringReader, StringBufferInputStream).
Torude tegemiseks on PipedInputStream ja PipedOutputStream (andmed) või PipedReader ja PipedWriter (tekst).
Puhverdatud voogude klassinime prefiks on Buffered...
Print... klassid ei anna erindeid ning sisaldavad muid mugavusi (näit. print- ja println-meetodid paljude tüüpide jaoks).
Lihttüüpide lugemiseks/kirjutamiseks tuleb kasutada klasse DataInputStream ja DataOutputStream või RandomAccessFile (tegelikult sobivad DataInput ja DataOutput liidesed, mida nimetatud klassid realiseerivad).
Puhverdatud voogude korral saab puhvri "jõuga" välja kirjutada kasutades flush()-meetodit.
Reeglina on voogudel kaks taset, mille määravad voo kasutuseesmärk (ülemine tase) ning kandja ("aluspõhi").
Voo "aluspõhi" määratakse üldiselt voo loomisel, näit.
BufferedReader sisendvoog =
Meetodeid: exists, canRead, canWrite, isFile, isDirectory, isAbsolute, getName, getPath, getAbsolutePath, getParent, lastModified, length, mkdir, mkdirs, list, renameTo, delete
Toru "tootjapoolne ots" kuulub ühte klassidest PipedOutputStream (andmed) või PipedWriter (tekst), "tarbijapoolne ots" on vastavalt PipedInputStream või PipedReader. Otsad on iseseisvad objektid ja neid saab ühendada dünaamiliselt (connect) (muidugi saab seda teha ka "teise otsa" loomisel, kui "esimene" on juba olemas). Reeglina alustab ja lõpetab tootja omad operatsioonid toruga enne tarbijat, kuid lõplikult suletakse toru tarbija poolt.
Järgnevates näidetes mitte unustadaimport java.io.*;Tekstirea lugemine standardsisendist
Standardsisend on muutujas System.in, vaikimisi vastab sellele klaviatuur.try {
BufferedReader sisse = new BufferedReader
(new InputStreamReader (System.in));
System.out.print ("Anna tekst: ");
String s = sisse.readLine(); // rida teksti ka"es
System.out.println ("Tippisid: " + s);
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Teksti kirjutamine faili
try {
PrintWriter valjund = new PrintWriter
(new FileWriter ("tekst.txt"), true);
valjund.println ("Esimene rida");
valjund.println ("Teine rida ja\nkolmas rida");
valjund.close();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Teksti lugemine failist
try {
BufferedReader sisend = new BufferedReader
(new FileReader ("tekst.txt"));
String rida;
while ((rida = sisend.readLine()) != null) {
// rida olemas, vo~ime to"o"delda
System.out.println (rida);
}
sisend.close();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Andmete kirjutamine faili
try {
DataOutputStream valjundvoog =
new DataOutputStream
(new FileOutputStream ("andmed.bin"));
valjundvoog.writeInt (1234);
valjundvoog.writeDouble (1.23e4);
valjundvoog.close();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Andmete lugemine failist (struktuur teada)
try {
DataInputStream sisendvoog = new DataInputStream
(new FileInputStream ("andmed.bin"));
int n = sisendvoog.readInt();
double d = sisendvoog.readDouble();
sisendvoog.close();
System.out.println ("Loeti: " + n + " ja " + d);
}
catch (EOFException e) { // oluline to"o"delda
System.out.println ("Faili lopp tuli ette: " + e);
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Andmete lugemine failist baithaaval
try {
FileInputStream voog = new FileInputStream
("andmed.bin");
System.out.println ("Baidid on: ");
int bait;
while ((bait = voog.read()) != -1) {
System.out.print (Integer.toHexString (bait) +
" ");
}
voog.close();
System.out.println();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
Faili lugemine baitmassiivi
try {
FileInputStream p = new FileInputStream
("tekst.txt");
byte[] sisu = new byte [p.available()];
p.read (sisu);
p.close();
// siin on meil kogu fail baitmassiivina
System.out.write (sisu);
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}Kataloogi sisu lugemine
File f = new File ("tmp"); // suval. kat. nimi
if (!f.exists() || !f.canRead()) {
System.out.println ("Ei saa lugeda: " + f);
return;
}
if (f.isDirectory()) {
String [] nimekiri = f.list(); // String-massiiv
for (int i=0; i < nimekiri.length; i++)
System.out.println (nimekiri [i]);
} else {
System.out.println ("Ei ole kataloog: " + f);
}Filter baidivoo tõlgendamiseks ja mälupuhver voo kandjana
//==============================================================
// rot13 filtri katsetamine ja ma"lupuhver faili rollis
//==============================================================
byte [] bfail = null; // bfail on baitmassiiv
System.out.println ("Kodeeritud faili kirjutamine.");
try {
// malu on va"ljundvoog, mille hiljem teeme massiiviks
ByteArrayOutputStream malu = new ByteArrayOutputStream();
// r13 on kodeeritud voog, mille kandjaks on malu
Rot13OutputStream r13 =
new Rot13OutputStream (malu);
r13.write ('A');
r13.write ('B');
r13.write ('C');
r13.write ('2');
r13.write ('n');
r13.write ('o');
r13.write ('p');
r13.write ('.');
r13.close();
bfail = malu.toByteArray(); // teise programmi jaoks meelde
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
System.out.println ("Kodeeritud fail:\n" + new String (bfail));
System.out.println ("Faili lugemine ja dekodeerimine.");
try {
Rot13InputStream r13 =
new Rot13InputStream (new ByteArrayInputStream (bfail));
int b;
System.out.println ("Dekodeeritud fail: ");
while ((b = r13.read()) != -1) {
System.out.print ((char)b);
}
System.out.println();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
.....
//=======================================================================
// Filtrid
//=======================================================================
class Rot13InputStream extends FilterInputStream {
Rot13InputStream (InputStream i) {
super (i);
}
public int read() throws IOException {
return rot13 (in.read()); // in on isendimuutuja
}
static int rot13 (int c) { // sama kasutame ka po"o"rdteisenduseks
if ((c >= 'A') && (c <= 'Z'))
c = 'A' + (((c - 'A') + 13) % 26);
if ((c >= 'a') && (c <= 'z'))
c = 'a' + (((c - 'a') + 13) % 26);
return c;
}
} // Rot13InputStream lopp
//====================================================================
class Rot13OutputStream extends FilterOutputStream {
Rot13OutputStream (OutputStream o) {
super (o);
}
public void write (int c) throws IOException {
out.write (Rot13InputStream.rot13 (c)); // out on isendimuutuja
}
} // Rot13OutputStream lopp
Tootja-tarbija sünkroniseerimine toru abil//======================================================================
// Torud (ingl.k. pipe)
//======================================================================
import java.io.*;
public class Torud {
public static void main (String[] parameetrid) {
try {
PipedOutputStream kirjutaja = new PipedOutputStream();
PipedInputStream lugeja = new PipedInputStream();
Tootja kirjutajaloim = new Tootja (kirjutaja);
Tarbija lugejaloim = new Tarbija (lugeja);
kirjutaja.connect (lugeja); // saab teisiti, aga su"mmetria
kirjutajaloim.start();
lugejaloim.start();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
} // main lopp
} // Torud lopp
//======================================================================
class Tootja extends Thread {
PipedOutputStream voog;
Tootja (PipedOutputStream p) {
voog = p;
}
public void run() {
System.out.println ("Tootja alustas... ");
try {
for (int i = 0; i < 9; i++) {
int r = (int)(Math.random()*256);
voog.write (r); // toode toodetud
System.out.println (i + ". toodetud: " + r);
try {
sleep ((int)(Math.random()*1000));
} catch (InterruptedException e) {}
}
voog.close(); // lugeja saab edasi lugeda
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
System.out.println ("Tootja lopetas");
}
} // Tootja lopp
//=================================================================
class Tarbija extends Thread {
PipedInputStream voog;
Tarbija (PipedInputStream p) {
voog = p;
}
public void run() {
System.out.println ("Tarbija alustas... ");
try {
int i = 0;
int r = -1;
while ((r = voog.read()) != -1) {
System.out.println (i++ + ". tarbitud: " + r);
try {
sleep ((int)(Math.random()*1000));
} catch (InterruptedException e) {}
}
voog.close(); // lugeja paneb lo~plikult kinni
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
System.out.println ("Tarbija lopetas");
}
} // Tarbija lopp
Märksõnu krüptograafiast üldiselt
Võtmed, võtmete genereerimine, haldamine (keystore), levitamine (Diffie-Hellman), ...
Java näide
/* Fail: Krypto.java
* Jaanus Pöial
*/
import java.io.*;
import java.security.*;
import java.security.cert.*;
import javax.crypto.*;
/**
* Krüptoklasside elemente.
* @author Jaanus Pöial
* @version kevad 2003
* @since 1.4
*/
public class Krypto {
/**
* peameetod.
* @param p käsurida
*/
public static void main (String[] p) {
try {
// asümmeetrilise algoritmi jaoks võtmepaari genereerimine
// RSA - Rivest, Shamir, Adleman 1978
KeyPairGenerator pgen = KeyPairGenerator.getInstance ("RSA");
pgen.initialize (1024); // 2048 on lubatud
KeyPair paar = pgen.generateKeyPair();
PublicKey avavoti = paar.getPublic(); // avalik võti
PrivateKey privavoti = paar.getPrivate(); // privaatne võti
// sümmeetrilise algoritmi jaoks võtme genereerimine
// "Triple-DES"
KeyGenerator vgen = KeyGenerator.getInstance ("DESede");
vgen.init (112); // 168 lubatud
SecretKey salavoti = vgen.generateKey(); // salajane võti
// võtmehoidla, võtmete salvestamine ja lugemine
KeyStore hoidla = KeyStore.getInstance ("JCEKS");
hoidla.load (null, "parool".toCharArray());
hoidla.setKeyEntry ("avalik", avavoti, "parool2".toCharArray(), null);
hoidla.setKeyEntry ("sala", salavoti, "parool3".toCharArray(), null);
// privaatvõtit saab salvestada ainult sertifikaadiga
// lugemine algab tegelikult load-st, mis praegu on tehtud
Key voti = hoidla.getKey ("avalik", "parool2".toCharArray());
FileOutputStream fos = new FileOutputStream ("votmed");
hoidla.store (fos, "parool".toCharArray());
fos.close();
// allkirjastamine privaatvõtmega
Signature sgn = Signature.getInstance ("MD5withRSA");
sgn.initSign (privavoti);
byte[] teade = "Sellele lausele annan allkirja".getBytes();
sgn.update (teade);
byte[] tulemus = sgn.sign(); // allkirjastatud baitmassiiv
// allkirja kontrollimine avaliku võtmega
sgn.initVerify ((PublicKey)voti);
sgn.update (teade);
if (sgn.verify (tulemus))
System.out.println ("Qige allkiri: " + sgn.toString());
else System.out.println ("Vale allkiri: " + sgn.toString());
// allkirjastatud objekt
Serializable objekt = "See on üks väga tähtis objekt";
SignedObject aobjekt = new SignedObject (objekt, privavoti, sgn);
String tmp = (String)aobjekt.getObject();
System.out.println (tmp);
if (aobjekt.verify (avavoti, sgn)) System.out.println ("OK");
else System.out.println ("Ei klapi");
// räsimine
MessageDigest md5 = MessageDigest.getInstance ("MD5");
md5.reset(); // praegusel hetkel saab ka ilma selleta
byte[] sonum = "arvutatakse räsi (128 bitti)".getBytes();
md5.update (sonum);
byte[] rasi = md5.digest(); // sõnumilühend
System.out.print ("Sõnumilühend: ");
for (int i=0; i<rasi.length; i++) {
System.out.print (Integer.toHexString (rasi [i]&0xff) + " ");
}
System.out.println();
// krüptimine sümmeetrilise algoritmiga
Cipher shiffer = Cipher.getInstance ("DESede");
shiffer.init (Cipher.ENCRYPT_MODE, salavoti);
byte[] avatekst = "See on suur saladus".getBytes();
// pikema teate korral osamassiivid saadakse update abil
byte[] shiffertekst = shiffer.doFinal (avatekst); // shifreeritud
// dekrüptimine
shiffer.init (Cipher.DECRYPT_MODE, salavoti);
byte[] tagasi = shiffer.doFinal (shiffertekst);
System.out.println (new String (tagasi));
// krüptitud voog - kirjutamine
FileInputStream avavoog1 = new FileInputStream ("andmed");
FileOutputStream krvoog1 = new FileOutputStream ("krandmed");
shiffer.init (Cipher.ENCRYPT_MODE, salavoti);
CipherOutputStream cout = new CipherOutputStream (krvoog1, shiffer);
int b;
while ((b = avavoog1.read()) != -1) {
cout.write (b);
}
cout.close();
// krüptitud voog - lugemine
FileInputStream krvoog2 = new FileInputStream ("krandmed");
FileOutputStream avavoog2 = new FileOutputStream ("andmed2");
shiffer.init (Cipher.DECRYPT_MODE, salavoti);
CipherInputStream cin = new CipherInputStream (krvoog2, shiffer);
while ((b = cin.read()) != -1) {
avavoog2.write (b);
}
avavoog2.close();
// X509 sertifikaadi lugemine failist
// vaata keytool-programmi sertifikaatide jaoks
CertificateFactory cfac = CertificateFactory.getInstance ("X.509");
InputStream svoog = new FileInputStream ("sertifikaat");
X509Certificate cert =
(X509Certificate)cfac.generateCertificate (svoog);
svoog.close();
}
catch (Exception e) {
System.out.println ("Jama " + e.toString());
}
} // main lopp
} // Krypto lopp