Java Language
InputStreams i OutputStreams
Szukaj…
Składnia
- int read (byte [] b) zgłasza wyjątek IOException
Uwagi
Zauważ, że przez większość czasu NIE używasz bezpośrednio InputStream
s, ale używasz BufferedStream
s lub podobnego. Jest tak, ponieważ InputStream
czyta ze źródła za każdym razem, gdy wywoływana jest metoda read. Może to powodować znaczne zużycie procesora podczas przełączania kontekstu do i z jądra.
Odczytywanie InputStream w ciąg
Czasami możesz chcieć odczytać dane wejściowe bajtu w ciągu znaków. Aby to zrobić, musisz znaleźć coś, co konwertuje między byte
a „natywną” Java Codepoints UTF-16 używaną jako char
. Odbywa się to za pomocą InputStreamReader
.
Aby nieco przyspieszyć proces, „zwykle” przydziela się bufor, abyśmy nie mieli zbyt dużego narzutu podczas odczytu z Input.
public String inputStreamToString(InputStream inputStream) throws Exception {
StringWriter writer = new StringWriter();
char[] buffer = new char[1024];
try (Reader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
int n;
while ((n = reader.read(buffer)) != -1) {
// all this code does is redirect the output of `reader` to `writer` in
// 1024 byte chunks
writer.write(buffer, 0, n);
}
}
return writer.toString();
}
Przekształcenie tego przykładu w kod kompatybilny z Java SE 6 (i niższymi wersjami) jest pomijane jako ćwiczenie dla czytelnika.
Zapisywanie bajtów do OutputStream
Zapisywanie bajtów do OutputStream
jednym bajcie
OutputStream stream = object.getOutputStream();
byte b = 0x00;
stream.write( b );
Pisanie tablicy bajtów
byte[] bytes = new byte[] { 0x00, 0x00 };
stream.write( bytes );
Pisanie sekcji tablicy bajtów
int offset = 1;
int length = 2;
byte[] bytes = new byte[] { 0xFF, 0x00, 0x00, 0xFF };
stream.write( bytes, offset, length );
Zamykanie strumieni
Większość strumieni musi zostać zamknięta po ich zakończeniu, w przeciwnym razie możesz wprowadzić wyciek pamięci lub pozostawić otwarty plik. Ważne jest, aby strumienie były zamykane, nawet jeśli zostanie zgłoszony wyjątek.
try(FileWriter fw = new FileWriter("outfilename");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
//more code
out.println("more text");
//more code
} catch (IOException e) {
//handle this however you
}
Pamiętaj: try-with-resources gwarantuje, że zasoby zostały zamknięte po wyjściu z bloku, niezależnie od tego, czy dzieje się tak przy zwykłym przepływie sterowania, czy z powodu wyjątku.
Czasami try-with-resources nie wchodzi w grę, a może wspierasz starszą wersję Java 6 lub starszą. W takim przypadku poprawną obsługą jest użycie bloku finally
:
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
fw = new FileWriter("myfile.txt");
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
out.println("the text");
out.close();
} catch (IOException e) {
//handle this however you want
}
finally {
try {
if(out != null)
out.close();
} catch (IOException e) {
//typically not much you can do here...
}
}
Pamiętaj, że zamknięcie strumienia opakowania również zamknie jego strumień bazowy. Oznacza to, że nie można owinąć strumienia, zamknąć opakowania, a następnie kontynuować korzystanie z oryginalnego strumienia.
Kopiowanie strumienia wejściowego do strumienia wyjściowego
Ta funkcja kopiuje dane między dwoma strumieniami -
void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
}
Przykład -
// reading from System.in and writing to System.out
copy(System.in, System.out);
Zawijanie strumieni wejściowych / wyjściowych
OutputStream
i InputStream
mają wiele różnych klas, z których każda ma unikalną funkcjonalność. Owijając strumień wokół drugiego, zyskujesz funkcjonalność obu strumieni.
Możesz owinąć strumień dowolną liczbę razy, po prostu zanotuj jego kolejność.
Przydatne kombinacje
Zapisywanie znaków do pliku podczas używania bufora
File myFile = new File("targetFile.txt");
PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(myFile)));
Kompresowanie i szyfrowanie danych przed zapisaniem do pliku przy użyciu bufora
Cipher cipher = ... // Initialize cipher
File myFile = new File("targetFile.enc");
BufferedOutputStream outputStream = new BufferedOutputStream(new DeflaterOutputStream(new CipherOutputStream(new FileOutputStream(myFile), cipher)));
Lista opakowań Strumienia wejścia / wyjścia
Obwoluta | Opis |
---|---|
BufferedOutputStream / BufferedInputStream | Podczas gdy OutputStream zapisuje dane po jednym bajcie, BufferedOutputStream zapisuje dane we fragmentach. Zmniejsza to liczbę wywołań systemowych, a tym samym poprawia wydajność. |
DeflaterOutputStream / DeflaterInputStream | Wykonuje kompresję danych. |
InflaterOutputStream / InflaterInputStream | Wykonuje dekompresję danych. |
CipherOutputStream / CipherInputStream | Szyfruje / odszyfrowuje dane. |
DigestOutputStream / DigestInputStream | Generuje podsumowanie wiadomości w celu weryfikacji integralności danych. |
CheckedOutputStream / CheckedInputStream | Generuje CheckSum. CheckSum to bardziej trywialna wersja Message Digest. |
DataOutputStream / DataInputStream | Umożliwia zapis prymitywnych typów danych i ciągów. Przeznaczony do pisania bajtów. Niezależna od platformy. |
PrintStream | Umożliwia zapis prymitywnych typów danych i ciągów. Przeznaczony do pisania bajtów. Zależny od platformy. |
OutputStreamWriter | Konwertuje OutputStream na Writer. OutputStream zajmuje się bajtami, a Writers - postaciami |
PrintWriter | Automatycznie wywołuje OutputStreamWriter. Umożliwia zapis prymitywnych typów danych i ciągów. Ściśle do pisania znaków i najlepiej do pisania znaków |
Przykład DataInputStream
package com.streams;
import java.io.*;
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
InputStream input = new FileInputStream("D:\\datastreamdemo.txt");
DataInputStream inst = new DataInputStream(input);
int count = input.available();
byte[] arr = new byte[count];
inst.read(arr);
for (byte byt : arr) {
char ki = (char) byt;
System.out.print(ki+"-");
}
}
}