Jelenlegi hely

20.1.2 Szűrő adatfolyamok

A java.io csomag tartalmazza az absztrakt osztályok speciális beállításainak lehetőségét, mellyel definiálhatunk, és részlegesen implementálhatunk szűrőket, olvasás, illetve írás céljából. A használatos filter adatfolyamok a FilterInputStream, FilterOutputStream. Egy filter adatfolyam egy másik alapadatfolyamra épül, melybe a write metódus fog adatokat menteni, de csak a szűrés után. Vannak adatfolyamok, melyek speciális feladatokat látnak el, mint például a konvertálás vagy számlálás folyamata.

A legtöbb filter adatfolyamot a java.io csomag által szolgáltatott származtatott osztályok nyújtják, ezek a következők:

  • DataInputStream és DataOutputStream
  • BufferedInputStream és BufferedOutputStream
  • LineNumberInputStream
  • PushbackInputStream
  • PrintStream

A java.io csomag csak egy származtatott osztályát tartalmazza a FilterReader-nek, ez nem más, mint a PushbackReader. A következő fejezet bemutatja egy példán szemléltetve, hogyan használjuk a szűrő adatfolyamokat a DataInputStream és a DataOutStream használatával. Ugyancsak tárgyalja, hogyan hozhatunk létre származtatott osztályokat a FilterInputStream és FilterOutputStream-ből, melyek segítségével saját szűrő adatfolyamunkat valósíthatjuk meg.

Szűrő adatfolyamok használata

A szűrő objektumokat csatolni kell egy másik I/O adatfolyamhoz, példaként csatolhatunk szűrő adatfolyamot a standard input adatfolyamra:

BufferedReader d = new BufferedReader(new
    DataInputStream(System.in));
String input;

while ((input = d.readLine()) != null) {
    ... //do something interesting here
}

Megjegyzés: A readLine metódus nem használható a DataInputStream-ben, ezért hoztuk létre a BufferedReader típusú d szűrő objektumot.

A következőkben egy példán szemléltetjük a DataInputStream és DataOutputStream használatát. Ezek olyan szűrők melyek képesek írni/olvasni elemi adattípusokat.

Előfordul, hogy a feldolgozás független a kezelt adat formátumától, de néha szorosan összefügg az illető adatokkal vagy annak formátumaival, úgymint adatok írása, olvasása sorokból vagy cellákból.

DataInputStream és DataOutputStream használata

Ez a fejezet a DataInutStream és DataOutputStream osztályok használatát mutatja be egy DataIODemo példaprogramon keresztül, mely olvas és ír táblázatba (cellákba) foglalt adatokat. A cellák tartalmazzák az eladási árat, a rendelt áru mennyiségét, és a leírást. Elméletileg az adat a következőképpen néz ki, habár a gép ezt bináris adatként kezeli:

19.99   12      Java T-shirt
9.99    8       Java Mug

DataOutputStream-et, mint ahogyan más kimeneti adatfolyamokat, csatolni kell egy másik OutputStream-hez. Ebben az esetben a FileOutputStream-hez csatoltuk. Példa:
DataOutputStream out = new DataOutputStream(
                        new FileOutputStream("invoice1.txt"));

A DataIODemo a DataOutputStream speciális write metódusait használja írásra, amennyiben az megfelelő típusú.
for (int i = 0; i < prices.length; i ++) {
    out.writeDouble(prices[i]);
    out.writeChar('\t');
    out.writeInt(units[i]);
    out.writeChar('\t');
    out.writeChars(descs[i]);
    out.writeChar('\n');
}
out.close();

A DataIODemo program beolvassa az adatokat a DataInputStream speciális metódusai segítségével:
try {
    while (true) {
        price = in.readDouble();
        in.readChar();       //throws out the tab
        unit = in.readInt();
        in.readChar();       //throws out the tab
        char chr;
        desc = new StringBuffer(20);
        char lineSep =
            System.getProperty("line.separator").charAt(0);
        while ((chr = in.readChar() != lineSep) {
            desc.append(chr);
        }
        System.out.println("You've ordered " + unit
            +  " units of "
                           + desc + " at $" + price);
        total = total + unit * price;
    }   
} catch (EOFException e) { }
System.out.println("For a TOTAL of: $" + total);
in.close();

Mihelyst beolvasta az adatokat, a DataIODemo megjeleníti az összegzést, a rendelt és az összes mennyiséget, majd bezárul.

Megjegyzés: a DataIODemo által használt ciklus a DataInputStream-ből olvassa az adatokat:

while ((input = in.read()) != null) {
    . . .
}

A read metódus null értékkel tér vissza, mely a fájl végét jelenti.

Számos alkalommal azonban ezt nem tehetjük meg, a szabálytalanul megadott értékek esetén hibajelzést kapunk. Tegyük fel, hogy -1 értéket szeretnénk ugyanerre a célra felhasználni. Ezt nem tehetjük meg, ugyanis a -1 nem szabályos érték, kiolvasása a readDoublevagy readInt használatával történik. Tehát DataInputStream-ek esetén nem kapunk EOFException kivételt.

A program futása a következő kimenetet eredményezi:

You've ordered 12 units of Java T-shirt at $19.99
You've ordered 8 units of Java Mug at $9.99
You've ordered 13 units of Duke Juggling Dolls at $15.99
You've ordered 29 units of Java Pin at $3.99
You've ordered 50 units of Java Key Chain at $4.99
For a TOTAL of: $892.8800000000001