// máme libovolný InputStream is
is = new InputStream(...);
// bis přidá k proudu is vlastnost vyrovnávací paměti
bis = new BufferedInputStream(is);
typ dat |
vstupní |
výstupní |
znakové |
Reader |
Writer |
binární |
InputStream |
OutputStream |
Proudy jsou koncipovány jako "stavebnice": lze je spojovat za sebe a tím přidávat vlastnosti, např.
// máme libovolný InputStream is
is = new InputStream(...);
// bis přidá k proudu is vlastnost vyrovnávací paměti
bis = new BufferedInputStream(is);
odvozeny od abstraktní třídy InputStream, např. FileInputStream.
odvozeny od abstraktní třídy OutputStream, např. FileOutputStream.
V reálu to takto neděláme, protože
public class CopyFile {
public static void main(String args[]) throws IOException {
FileReader in = null;
FileWriter out = null;
try {
in = new FileReader("input.txt");
out = new FileWriter("output.txt");
int c;
// ve skutečnosti je v c opravdu bajt (nebo -1)
while ((c = in.read()) != -1) {
out.write(c);
}
} finally { // nutné pro korektní zavření za všech okolností
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
uzavře proud a uvolní příslušné zdroje (systémové "file handles" apod.)
poznačí si aktuální pozici (později se lze vrátit zpět pomocí reset())
ale jen když platí tohle
přečte bajt (0-255 pokud OK; jinak -1, když už není možné přečíst)
přečte pole bajtů
přečte pole bajtů se specifikací délky a pozice plnění pole b
vrátí se ke značce nastavené metodou mark(int)
přeskočí zadaný počet bajtů
je bázová třída k odvozování všech vstupních proudů přidávajících vlastnost/schopnost filtrovat poskytnutý vstupní proud.
Příklady filtrů (ne všechny jsou v java.io):
proud s vyrovnávací pamětí (je možno specifikovat její optimální velikost)
proud s kontrolním součtem (např. CRC32)
proud dešifrující data ze vstupu
má metody pro čtení hodnot primitivních typů, např. float readFloat()
počítá současně i haš (digest) čtených dat, použitý algoritmus lze nastavit
dekomprimuje (např. GZIPem) zabalený vstupní proud (má ještě specializované podtřídy)
doplňuje informaci o tom, ze kterého řádku vstupu čteme (zavrhovaná — deprecated — třída)
přidává schopnost informovat o průběhu čtení z proudu
do proudu lze data vracet zpět
Příklad rekonstrukce objektů ze souborů:
FileInputStream istream = new FileInputStream("t.tmp");
ObjectInputStream p = new ObjectInputStream(istream);
int i = p.readInt();
String s = (String)p.readObject();
Date d = (Date)p.readObject();
istream.close();
vstupní proud zvukových dat
proud dat čtených z pole bajtů
roura napojená na "protilehlý" PipedOutputStream
proud vzniklý spojením více podřízených proudů do jednoho virtuálního
proud na čtení serializovaných objektů
Konkrétními implementacemi jsou:
Za pozornost stojí PrintStream:
Ze vstupního binárního proudu InputStream (čili každého) je možné vytvořit znakový Reader pomocí
// nejprve binární vstupní proud, ten kódování znaků nezajímá
InputStream is = ...
// znakový proud isr
// použije pro dekódování standardní znakovou sadu
Reader isr = new InputStreamReader(is);
// sady jsou definovány v balíku java.nio
Charset chrs = java.nio.Charset.forName("ISO-8859-2");
// znakový proud isr2
// použije pro dekódování jinou znakovou sadu
Reader isr2 = new InputStreamReader(is, chrs);
Tradičně (před Java 7) se muselo dělat blokem finally:
String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
Nabízí nově tzv. try-with-resources:
String readFirstLineFromFile(String path) throws IOException {
// toto je "try with resources", automaticky proud zavře
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Pomocí try-with-resources lze ošetřit i více proudů současně — zavřou se pak všechny.
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset))
je typ proudu standardního i chybového výstupu System.out.
pro znaková data
Příklad s nastavením kódování:
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
Nebudeme podrobně studovat, zatím stačí vědět, že:
postup, jak z objektu vytvořit sekvenci bajtů perzistentně uložitelnou na paměťové médium (disk) a později restaurovatelnou do podoby výchozího javového objektu.
je právě zpětná rekonstrukce objektu
Tutoriál essential Java I/O: kapitola z Oracle Java Tutorial
/