Naučte se Javu – práce se vstupy a výstupy 2.
Dnes navážeme na téma z minulého článku, ve kterém jsme si vysvětlili základní principy vstupů a výstupů. Ukážeme si dvě konkrétní aplikace vstupních a výstupních proudů – tvorbu filtrů vstupních dat a bufferování výstupu.
Filtrování vstupu
Následníky třídy FilterInputStream
lze provádět filtrování vstupních dat pomocí uživatelsky definovaného filtru. Třída má jako parametr konstruktoru vstupní proud, ze kterého čte data určená k filtrování. Vlastní filtrování dat se provádí v metodách read()
, které musí programátor implementovat.
Příklad 1: textový filtr
Následující příklad ukazuje textový filtrovací vstupní proud, který převádí znaky na velká písmena (VelkaPismenaInputStream.java):
import java.io.*;
public class VelkaPismenaInputStream extends FilterInputStream {
// konstruktor volá standardní konstruktor
public VelkaPismenaInputStream(InputStream in) {
super(in);
}
// čtení jednoho znaku
public int read() throws IOException {
char ch = (char)in.read(); // načtení znaku
return Character.toUpperCase(ch); // převedení na velké písmeno
}
// čtení pole znaků
public int read(byte[] b) throws IOException {
int len = in.read(b, 0, b.length);
for (int i=0; i<len; i++) b[i] = (byte)Character.toUpperCase((char)b[i]);
return len;
}
// čtení části pole znaků dané počátkem a délkou
public int read(byte[] b, int off, int len) throws IOException {
len = in.read(b, 0, len);
for (int i=0; i<len; i++) b[off+i] = (byte)Character.toUpperCase((char)b[off+i]);
return len;
}
}
Příklad 2: použití filtru
Pro otestování filtru stačí nepatrná úprava příkladu copy
z minulého článku. Jednalo se o aplikaci pro kopírování souborů (podle parametrů příkazového řádku). Pro úpravu použijeme popsané v minulém díle a řádek vstup = new FileInputStream(args[0]);
nahradíme řádkem vstup = new VelkaPismenaInputStream(new FileInputStream(args[0]));
. Tím vložíme do posloupnosti proudů filtr (data půjdou z FileInputStream
do VelkaPismenaInputStream
) a výsledkem bude program, který kopíruje soubor s převodem na velká písmena (copy2vp.java):
import java.io.*;
public class copy2vp {
public copy2vp() {
}
public static void main(String[] args) {
if (args.length<2) {
System.out.println(„Syntaxe: java copy <soubor1> <soubor2>“);
return;
}
InputStream vstup = null;
OutputStream vystup = null;
// otevreni prvního souboru pro čtení a založení vstupního proudu
try {
vstup = new VelkaPismenaInputStream(new FileInputStream(args[0]));
} catch (IOException e) {
System.out.println(„Soubor „+args[0]+“ se nepodarilo otevrit!“);
return;
}
// otevření druhého souboru pro zápis a založení výstupního proudu
try {
vystup = new FileOutputStream(args[1]);
} catch (IOException e) {
System.out.println(„Soubor „+args[1]+“ se nepodarilo vytvorit!“);
return;
}
// kopírování obsahu souboru
byte data[] = new byte[1024]; // obsah suoboru přenášíme po 1kB blocích
int pocet;
try {
while (vstup.available()>0) {
pocet = vstup.read(data); // počet skutečně přenesených bytů
vystup.write(data, 0, pocet);
}
}
catch (IOException ex) {
System.out.println(„Nastala chyba pri kopirovani souboru!“);
}
}
}
Podobným způsobem je možné naprogramovat proud, který převádí znaky mezi různými kódováními češtiny, a z programu copy tak vytvořit převaděč znakových sad. Rovněž existuje třída FilterInputStream
, která pro změnu filtruje výstupní data a v tomto příkladě by šla také použít.
Bufferování výstupu
Představte si problém: kódujete data, potřebujete poslat délku kódované zprávy a pak její obsah. Jak to ale vyřešit, pokud data zapisujete do výstupního proudu a na počátku tedy nevíte, kolik jich bude?!
Pomůže nám výstupní proud ByteArrayOutputStream
. Jak pracuje? Do ByteArrayOutputStream
zapisujete data, ale ten je neposílá dál, nýbrž si je uchovává ve vnitřním bufferu. Můžete je kdykoli vypsat do jiného výstupního proudu metodou writeTo(OutputStream out)
.
Příklad 3: kodujdelku.java
Pravděpodobně bychom takto kódovanou zprávu posílali například jiné aplikaci po síti, pro jednoduchost si však ukážeme, jak by se vypsala do souboru. Program vypíše svůj standardní vstup na standardní výstup s tím, že mu předchází počet bytů, kódovaný jako 4-bytový integer (kodujdelku.java):
import java.io.*;
public class kodujdelku {
public kodujdelku() {
}
public static void main(String[] args) {
DataOutputStream vystup = new DataOutputStream(System.out);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataInputStream vstup = new DataInputStream(System.in);
try {
while (vstup.available()>0) buffer.write(System.in.read());
vystup.writeInt(buffer.size());
buffer.writeTo(vystup);
}
catch (IOException ex) {
System.out.println(„Chyba pri cteni ze standardniho vstupu“);
return;
}
}
}
Zkompilovaný program zavoláte z příkazového řádku: java interval.kodujdelku <vstup.bin >vystup.bin
. Takto lze bufferování využívat pro počítání CRC, šifrování nebo třeba pro implementaci MP3 kodeku. Zkrátka kdekoli, kde dostáváme data postupně a chceme je zpracovat najednou.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
10 nejpopulárnějších programovacích jazyků a jejich využití
9. listopadu 2023 -
Užitečné nástroje pro bezpečnost na internetu
17. října 2024 -
Landing page: Jak vytvořit landing page s vysokým CTR
7. května 2024 -
Certifikáty Entrust ztratí důvěru Google Chrome
8. července 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024