Java Language
InputStreams и OutputStreams
Поиск…
Синтаксис
- int read (byte [] b) выбрасывает IOException
замечания
Обратите внимание, что большую часть времени вы НЕ используете InputStream
s напрямую, но используете BufferedStream
или похожи. Это связано с тем, что InputStream
считывает из источника каждый раз при вызове метода чтения. Это может вызвать значительное использование ЦП в контекстных коммутаторах в ядре и из него.
Чтение InputStream в строку
Иногда вы можете читать байтовый ввод в String. Для этого вам нужно будет найти что-то, что преобразует между byte
и «родной Java» UTF-16 Codepoints, используемым как char
. Это делается с помощью InputStreamReader
.
Чтобы немного ускорить процесс, «обычным» является выделение буфера, так что у нас не слишком много накладных расходов при чтении с 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();
}
Преобразование этого примера в Java SE 6 (и более низкий) совместимый код не учитывается как упражнение для читателя.
Запись байтов в OutputStream
Запись байтов в OutputStream
одному байту за раз
OutputStream stream = object.getOutputStream();
byte b = 0x00;
stream.write( b );
Запись байтового массива
byte[] bytes = new byte[] { 0x00, 0x00 };
stream.write( bytes );
Написание раздела массива байтов
int offset = 1;
int length = 2;
byte[] bytes = new byte[] { 0xFF, 0x00, 0x00, 0xFF };
stream.write( bytes, offset, length );
Закрытие потоков
Большинство потоков необходимо закрыть, когда вы закончите с ними, иначе вы можете ввести утечку памяти или оставить файл открытым. Важно, чтобы потоки были закрыты, даже если выбрано исключение.
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
}
Помните: try-with-resources гарантирует, что ресурсы были закрыты при выходе из блока, независимо от того, происходит ли это с обычным потоком управления или из-за исключения.
Иногда попробовать-с-ресурсами не вариант, или, может быть, вы поддерживаете более старую версию Java 6 или ранее. В этом случае правильная обработка заключается в использовании блока 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...
}
}
Обратите внимание, что закрытие потока оболочки также закрывает его базовый поток. Это означает, что вы не можете обернуть поток, закрыть оболочку и продолжить использование исходного потока.
Копирование входного потока в выходной поток
Эта функция копирует данные между двумя потоками -
void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
}
Пример -
// reading from System.in and writing to System.out
copy(System.in, System.out);
Обтекание потоков ввода / вывода
OutputStream
и InputStream
имеют много разных классов, каждый из которых обладает уникальной функциональностью. Обертывая поток вокруг другого, вы получаете функциональность обоих потоков.
Вы можете обтекать поток сколько угодно раз, просто обратите внимание на порядок.
Полезные комбинации
Запись символов в файл при использовании буфера
File myFile = new File("targetFile.txt");
PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(myFile)));
Сжатие и шифрование данных перед записью в файл при использовании буфера
Cipher cipher = ... // Initialize cipher
File myFile = new File("targetFile.enc");
BufferedOutputStream outputStream = new BufferedOutputStream(new DeflaterOutputStream(new CipherOutputStream(new FileOutputStream(myFile), cipher)));
Список оберток потока ввода / вывода
обертка | Описание |
---|---|
BufferedOutputStream / BufferedInputStream | В то время как OutputStream записывает данные по одному байту за один раз, BufferedOutputStream записывает данные в куски. Это уменьшает количество системных вызовов, что повышает производительность. |
DeflaterOutputStream / DeflaterInputStream | Выполняет сжатие данных. |
InflaterOutputStream / InflaterInputStream | Выполняет декомпрессию данных. |
CipherOutputStream / CipherInputStream | Шифрует / расшифровывает данные. |
DigestOutputStream / DigestInputStream | Генерирует дайджест сообщений для проверки целостности данных. |
CheckedOutputStream / CheckedInputStream | Создает CheckSum. CheckSum - это более тривиальная версия Message Digest. |
DataOutputStream / DataInputStream | Позволяет писать примитивные типы данных и строки. Предназначен для написания байтов. Независимая платформа. |
PrintStream | Позволяет писать примитивные типы данных и строки. Предназначен для написания байтов. Платформа зависит. |
OutputStreamWriter | Преобразует OutputStream в Writer. OutputStream имеет дело с байтами, в то время как Writers имеет дело с символами |
PrintWriter | Автоматически вызывает OutputStreamWriter. Позволяет писать примитивные типы данных и строки. Строго для написания символов и лучше всего писать символы |
Пример 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+"-");
}
}
}