Класс InputStream
Базовый класс InputStream представляет классы, которые получают данные из различных источников:
- массив байтов
- строка (String)
- файл
- канал (pipe): данные помещаются с одного конца и извлекаются с другого
- последовательность различных потоков, которые можно объединить в одном потоке
- другие источники (например, подключение к интернету)
Для работы с указанными источниками используются подклассы базового класса InputStream:
BufferedInputStream Буферизированный входной поток ByteArrayInputStream Позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока. DataInputStream Входной поток, включающий методы для чтения стандартных типов данных Java FileInputStream Для чтения информации из файла FilterInputStream Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства. InputStream Абстрактный класс, описывающий поток ввода ObjectInputStream Входной поток для объектов StringBufferInputStream Превращает строку (String) во входной поток данных InputStream PipedInputStream Реализует понятие входного канала. PushbackInputStream Входной поток, поддерживающий однобайтовый возврат во входной поток SequenceInputStream Сливает два или более потока InputStream в единый поток
- int available() — возвращает количество байтов ввода, доступные в данный момент для чтения
- close() — закрывает источник ввода. Следующие попытки чтения передадут исключение IOException
- void mark(int readlimit) — помещает метку в текущую точку входного потока, которая остаётся корректной до тех пор, пока не будет прочитано readlimint байт
- boolean markSupported() — возвращает true, если методы mark() и reset() поддерживаются потоком
- int read() — возвращает целочисленное представление следующего доступного байта в потоке. При достижении конца файла возвращается значение -1
- int read(byte[] buffer) — пытается читать байты в буфер, возвращая количество прочитанных байтов. По достижении конца файла возвращает значение -1
- int read(byte[] buffer, int byteOffset, int byteCount) — пытается читать до byteCount байт в buffer, начиная с смещения byteOffset. По достижении конца файла возвращает -1
- reset() — сбрасывает входной указатель в ранее установленную метку
- long skip(long byteCount) — пропускает byteCount байт ввода, возвращая количество проигнорированных байтов
Как преобразовать InputStream в строку
- Using IOUtils.toString (Apache Utils):
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8));
Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : "";
String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n"));
String result = new BufferedReader(new InputStreamReader(inputStream)).lines() .parallel().collect(Collectors.joining("\n"));
final int bufferSize = 1024; final char[] buffer = new char[bufferSize]; final StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(inputStream, "UTF-8"); for (; ; ) < int rsz = in.read(buffer, 0, buffer.length); if (rsz < 0) break; out.append(buffer, 0, rsz); >return out.toString();
StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString();
ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) < result.write(buffer, 0, length); >return result.toString("UTF-8");
String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(); String line; boolean flag = false; while ((line = reader.readLine()) != null) < result.append(flag? newLine: "").append(line); flag = true; >return result.toString();
BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while(result != -1) < buf.write((byte) result); result = bis.read(); >return buf.toString();
int ch; StringBuilder sb = new StringBuilder(); while((ch = inputStream.read()) != -1) sb.append((char)ch); reset(); return sb.toString();
BufferedInputStream
Буферизация ввода-вывода является удобным способом оптимизации производительности, позволяя заключить в оболочку любой поток класса InputStream. У класса есть конструктор, где размер буфера устанавливается по умолчанию. Также можно использовать конструктор, где размер буфера устанавливается вручную. Рекомендуется использовать размеры буфера, кратные размеру страницы памяти, дисковому блоку и т.п. и может зависеть от принимающей операционной системы, объёма доступной памяти и конфигурации машины.
ByteArrayInputStream
Класс ByteArrayInputStream использует байтовый массив в качестве источника данных. У данного класса можно не вызывать метод close().
DataInputStream — Форматированное чтение из памяти
Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream. Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream. При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов. Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных. Конструктор:
DataInputStream(InputStream stream)
FileInputStream
Класс FileInputStream создаёт объект класса InputStream, который можно использовать для чтения байтов из файла.
- FileInputStream (File file) — указывается объекта типа File
- FileInputStream (FileDescriptor fd)
- FileInputStream (String path) — указывается полное имя файла
При создании объект открывается для чтения. Класс переопределяет методы класса InputStream, кроме методов mark() и reset().
Для чтения байтов входного потока из файла используется конструкция:
File file = . InputStream in = null; try < in = new BufferedInputStream(new FileInputStream(file)); . finally < if (in != null) < in.close(); >> >
PushbackInputStream
Разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток. Класс PushbackInputStream представляет механизм «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий раз, не извлекая информации.
У класса есть дополнительный метод unread().
SequenceInputStream
Класс SequenceInputStream позволяет соединять вместе несколько экземпляров класса InputStream. Конструктор принимает в качестве аргумента либо пару объектов класса InputStream, либо интерфейс Enumeration.
Во время работы класс выполняет запросы на чтение из первого объекта класса InputStream и до конца, а затем переключается на второй. При использовании интерфейса работа продолжится по всем объектам класса InputStream. По достижении конца каждого файла, связанный с ним поток закрывается. Закрытие потока, созданного объектом класса SequenceInputStream, приводит к закрытию всех открытых потоков.
Java bufferedinputstream to string
Для оптимизации операций ввода-вывода используются буферизуемые потоки. Эти потоки добавляют к стандартным специальный буфер в памяти, с помощью которого повышается производительность при чтении и записи потоков.
Класс BufferedInputStream
Класс BufferedInputStream накапливает вводимые данные в специальном буфере без постоянного обращения к устройству ввода. Класс BufferedInputStream определяет два конструктора:
BufferedInputStream(InputStream inputStream) BufferedInputStream(InputStream inputStream, int bufSize)
Первый параметр — это поток ввода, с которого данные будут считываться в буфер. Второй параметр — размер буфера.
Например, буферизируем считывание данных из потока ByteArrayInputStream:
import java.io.*; public class Program < public static void main(String[] args) < String text = "Hello world!"; byte[] buffer = text.getBytes(); ByteArrayInputStream in = new ByteArrayInputStream(buffer); try(BufferedInputStream bis = new BufferedInputStream(in))< int c; while((c=bis.read())!=-1)< System.out.print((char)c); >> catch(Exception e) < System.out.println(e.getMessage()); >System.out.println(); > >
Класс BufferedInputStream в конструкторе принимает объект InputStream . В данном случае таким объектом является экземпляр класса ByteArrayInputStream .
Как и все потоки ввода BufferedInputStream обладает методом read() , который считывает данные. И здесь мы считываем с помощью метода read каждый байт из массива buffer.
Фактические все то же самое можно было сделать и с помощью одного ByteArrayInputStream, не прибегая к буферизированному потоку. Класс BufferedInputStream просто оптимизирует производительность при работе с потоком ByteArrayInputStream. Естественно вместо ByteArrayInputStream может использоваться любой другой класс, который унаследован от InputStream.
Класс BufferedOutputStream
Класс BufferedOutputStream аналогично создает буфер для потоков вывода. Этот буфер накапливает выводимые байты без постоянного обращения к устройству. И когда буфер заполнен, производится запись данных.
BufferedOutputStream определяет два конструктора:
BufferedOutputStream(OutputStream outputStream) BufferedOutputStream(OutputStream outputStream, int bufSize)
Первый параметр — это поток вывода, который унаследован от OutputStream, а второй параметр — размер буфера.
Рассмотрим на примере записи в файл:
import java.io.*; public class Program < public static void main(String[] args) < String text = "Hello world!"; // строка для записи try(FileOutputStream out=new FileOutputStream("notes.txt"); BufferedOutputStream bos = new BufferedOutputStream(out)) < // перевод строки в байты byte[] buffer = text.getBytes(); bos.write(buffer, 0, buffer.length); >catch(IOException ex) < System.out.println(ex.getMessage()); >> >
Класс BufferedOutputStream в конструкторе принимает в качестве параметра объект OutputStream — в данном случае это файловый поток вывода FileOutputStream. И также производится запись в файл. Опять же BufferedOutputStream не добавляет много новой функциональности, он просто оптимизирует действие потока вывода.