Oc-windows.ru

IT Новости из мира ПК
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Inputstreamreader java пример

Класс 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 в строку

  1. Using IOUtils.toString (Apache Utils):
  2. Using CharStreams (guava)
  3. Using Scanner (JDK)
    символ «А» является символом начала текста, таким образом вызов next() вернет сразу всю строку.
  4. Using Stream Api (Java 8). Warning: This solution convert different linebreaks (like rn) to n.
  5. Using parallel Stream Api (Java 8). Warning: This solution convert different linebreaks (like rn) to n.
  6. Using InputStreamReader and StringBuilder (JDK)
  7. Using StringWriter and IOUtils.copy (Apache Commons)
  8. Using ByteArrayOutputStream and inputStream.read (JDK)
  9. Using BufferedReader (JDK). Warning: This solution convert different linebreaks (like nr) to line.separator system property (for example, in Windows to «rn»).
  10. Using BufferedInputStream and ByteArrayOutputStream (JDK)
  11. Using inputStream.read() and StringBuilder (JDK). Warning: This soulition has problem with Unicode, for example with Russian text (work correctly only with non-Unicode text)

Warning:
Solutions 4, 5 and 9 convert different linebreaks to one.
Soulution 11 can’t work correclty with Unicode text

BufferedInputStream

Буферизация ввода-вывода является удобным способом оптимизации производительности, позволяя заключить в оболочку любой поток класса InputStream.

У класса есть конструктор, где размер буфера устанавливается по умолчанию. Также можно использовать конструктор, где размер буфера устанавливается вручную. Рекомендуется использовать размеры буфера, кратные размеру страницы памяти, дисковому блоку и т.п. и может зависеть от принимающей операционной системы, объёма доступной памяти и конфигурации машины.

ByteArrayInputStream

Класс ByteArrayInputStream использует байтовый массив в качестве источника данных. У данного класса можно не вызывать метод close().

DataInputStream — Форматированное чтение из памяти

Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.

Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.

При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.

Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.

FileInputStream

Класс FileInputStream создаёт объект класса InputStream, который можно использовать для чтения байтов из файла.

  • FileInputStream (File file) — указывается объекта типа File
  • FileInputStream (FileDescriptor fd)
  • FileInputStream (String path) — указывается полное имя файла

При создании объект открывается для чтения. Класс переопределяет методы класса InputStream, кроме методов mark() и reset().

Читать еще:  Регулярное выражение для email javascript

Для чтения байтов входного потока из файла используется конструкция:

PushbackInputStream

Разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток. Класс PushbackInputStream представляет механизм «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий раз, не извлекая информации.

У класса есть дополнительный метод unread().

SequenceInputStream

Класс SequenceInputStream позволяет соединять вместе несколько экземпляров класса InputStream. Конструктор принимает в качестве аргумента либо пару объектов класса InputStream, либо интерфейс Enumeration.

Во время работы класс выполняет запросы на чтение из первого объекта класса InputStream и до конца, а затем переключается на второй. При использовании интерфейса работа продолжится по всем объектам класса InputStream. По достижении конца каждого файла, связанный с ним поток закрывается. Закрытие потока, созданного объектом класса SequenceInputStream, приводит к закрытию всех открытых потоков.

InputStreamReader и OutputStreamWriter в Java

Классы InputStreamReader и OutputStreamWriter обеспечивают трансляцию между символьными и байтовыми потоками с учетом заданной кодировки символов или кодировки, принятой по умолчанию в конкретной локальной системе. Объекту InputStreamReader в качестве источника передается байтовый поток ввода, и InputStreamReader обеспечивает чтение соответствующих символов Unicode. Объекту OutputStreamWriter в качестве получателя передается байтовый поток вывода, и OutputStreamWriter сохраняет в нем байтовые представления символов Unicode. Следующий пример кода демонстрирует технику ввода байтов, представляющих символы арабского языка в кодировке ISO 8859-6, и преобразования их в соответствующие символы Unicode:

public Reader readArabic(String file) throws lOException <

InputStream filein = new FileinputStream(file);

return new lnputstreamReader(filein, «iso-8859-6»);

По умолчанию указанные классы, обеспечивающие преобразование потоков, работают с кодировкой символов, принятой в конкретной локальной системе, но Могут быть заданы и альтернативные кодировки. Классы играют роль связующего звена» и позволяют обрабатывать потоки 8-битовых символов, представленных в любых стандартных кодировках, в последовательном и сообразном стиле, не зависящем от особенностей применяемой платформы. Вопросы, вязанные со стандартами кодировки символов, рассмотрены в разделе 9.7.1. Описания конструкторов классов InputStreamReader и OutputStreamWriter приведены ниже.

Public InputStreamReader(inputStream in)

Создает объект InputStreamReader для ввода данных из указанного потока InputStream с учетом кодировки символов, принятой по умолчанию.

public InputStreamReader(inputstream in, String encoding)

Создает объект InputStreamReader для ввода данных из указанного по тока Inputstream с учетом заданной кодировки символов encoding. Если кодировка encoding не поддерживается, выбрасывается исключение типа UnsupportedEncodingException.

public 0utputStreamwriter(0utputStream out)

Создает объект OutputStreamwri ter для вывода данных в указанный поток OutputStream с учетом кодировки символов, принятой по умолчанию.

public OutputStreamwriter(OutputStream out, String encoding)

Создает объект OutputStreamWnter для вывода данных в указанный поток OutputStream с учетом заданной кодировки символов encoding. Если кодировка encoding не поддерживается, выбрасывается исключение типа UnsupportedEncodingException.

Методы read класса InputStreamReader обеспечивают ввод байтов из заданного потока Inputstream и преобразование их в символы с использованием соответствующей кодировки. Аналогично, методы write клксса OutputStreamWriter получают переданные символы, преобразуют их в байты, используя соответствующую кодировку, и выводят в заданный поток OutputStream.

В обоих классах при закрытии потока-преобразователя также закрывается и связанный с ним байтовый поток. Такое поведение не всегда желательно (скажем, при преобразовании данных из стандартных потоков), поэтому вопрос, когда именно следует закрывать поток InputStreamReader или OutputStreamWriter, заслуживает тщательного изучения.

В обоих классах поддерживается также метод getEncoding, возвращающий строку с каноническим наименованием кодировки, используемой потоком, либо значение null, если поток уже закрыт.

Классы FileReader и FileWriter являются расширенными версиями классов InputStreamReader и OutputStreamWriter соответственно и обеспечивают возможности обработки файловых данных с поддержкой Unicode и локальных стандартов кодировки символов. Если, однако, кодировка, предлагаемая по умолчанию, вас не устраивает, следует прибегнуть к помощи объектов InputStreamReader или OutputStreamWriter. Более подробные сведения о файловых потоках приведены в разделе 15.6 .

Классов ReaderlnputStream и WriterOutputStream, которые могли бы обеспечить трансляцию символьных потоков в байтовые и наоборот, не существует.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

Потоки ввода, InputStream

Существуют две параллельные иерархии классов ввода : InputStream и Reader. Класс Reader введен в последних версиях Java. В данной статье рассматривается вопрос использования потока байтового ввода InputStream, иерархия которого представлена на следующем рисунке.

Поток Stream— это абстрактное понятие источника или приёмника данных, которые способны обрабатывать информацию. Есть два типа потоков: байтовые и символьные. В некоторых ситуациях символьные потоки более эффективны, чем байтовые. Классы, производные от базовых InputStream или Reader, имеют методы read() для чтения отдельных байтов или массива байтов.

Читать еще:  Java concurrent list

Входной поток InputStream

Базовый класс InputStream — это абстрактный класс, определяющий входной поток данных, и является родителем для классов, получающих данные из различных источников : массив байтов, строки (String), файлы, каналы pipe, у которых одна из сторон является входом, а вторая сторона играет роль выхода, и т.д. Методы класса InputStream при возникновении ошибки вызывают исключение IOException.

Методы класса InputStream :

МетодОписание
boolean readBoolean()байт булевого однобайтового значения
byte readByte()байт одного байта
char readChar()байт значения char
double readDouble()байт восьмибайтового значения double
float readFloat()чтение четырехбайтового значения float
int readInt()чтение целочисленного значения int
long readLong()чтение значения long
short readShort()чтение значения short
String readUTF()чтение строки в кодировке UTF-8
int skipBytes(int n)пропуск при чтении n байтов

Пример чтения из бинарного файла с использованием DataInputStream

ObjectInputStream

Класс ObjectInputStream отвечает за чтение ранее сериализованных данных из потока. В конструкторе он принимает ссылку на поток ввода:

Основные методы класса ObjectInputStream :

Читать еще:  Java message service

У меня есть хобби: я собираю различные решения типовых задач в Java, которые нахожу в инете, и пытаюсь выбрать наиболее оптимальное по размеру/производительности/элегантности. В первую очередь по производительности. Давайте рассмотрим такую типовую задач, которые часто встречаются в программировании на Java как «преобразование InputStream в строку» и разные варианты её решения.

Посмотрим какие ограничения есть у каждого (требования подключения определенной библиотеки/определенной версии, корректная работа с unicode и т.д.). Английскую версию этой статьи можно найти в моем ответе на stackoverflow. Тесты в моем проекте на github.

Преобразование InputStream в строку (String)

Очень часто встречающая задача, давайте рассмотрим какими способами можно это сделать (их будет 11):

Используя IOUtils.toString из библиотеки Apache Commons . Один из самых коротких однострочников.

Используя CharStreams из библиотеки guava . Тоже довольно короткий код.

Используя Scanner (JDK). Решение короткое, хитрое, с помощью чистого JDK, но это скорее хак, который вынесет мозг тем кто о таком фокусе не знает.

Используя Stream Api с помощью Java 8 . Предупреждение: Оно заменяет разные переносы строки (такие как rn ) на n , иногда это может быть критично.

Используя parallel Stream Api ( Java 8 ). Предупреждение: Как и 4 решение, оно заменяет разные переносы строки (такие как rn ) на n .

Используя InputStreamReader и StringBuilder из обычного JDK

Используя StringWriter и IOUtils.copy из Apache Commons

Используя ByteArrayOutputStream и inputStream.read из JDK

Используя BufferedReader из JDK . Предупреждение: Это решение заменяет разные переносы строк (такие как nr ) на line.separator system property (например, в Windows на «rn»).

Используя BufferedInputStream и ByteArrayOutputStream из JDK

Используя inputStream.read() и StringBuilder ( JDK ). Предупреждение: Это решение не работает с Unicode, например с русским текстом

Итак о использовании:

Решения 4 , 5 и 9 преобразую разные переносы строки в одну.

Решения 11 не работает с Unicode текстом

  • Решение 1 , 7 требует использование библиотеки Apache Commons, 2 требует библиотеку Guava, 4 и 5 требуют Java 8 и выше,
  • Замеры производительности

    Предупреждение: замеры производительности всегда сильно зависят от системы, условий замера и т.п. Я измерял на двух разных компьютерах, один Windows 8.1, Intel i7-4790 CPU 3.60GHz2, 16Gb, второй — Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz2, 6Gb, однако не могу гарантировать что результаты являются абсолютной истиной, вы всегда можете повторить тесты (test1 и test2) на вашей системе.

    Замеры производительности для небольших строк (длина = 175), тесты можно найти на github (режим = среднее время выполнения (AverageTime), система = Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz*2, 6Gb, чем значение ниже тем лучше, 1,343 — наилучшее):

    Замеры производительности для больших строк (длина = 50100), тесты можно найти на github (режим = среднее время выполнения (AverageTime), система = Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz*2, 6Gb, чем значение ниже тем лучше, 200,715 — наилучшее):

    График зависимости среднего времени от длины строки, система Windows 8.1, Intel i7-4790 CPU 3.60GHz 3.60GHz, 16Gb:

    Таблица зависимости среднего времени от длины строки, система Windows 8.1, Intel i7-4790 CPU 3.60GHz 3.60GHz, 16Gb:

    Выводы

    Самым быстрым решением во всех случаях и всех системах оказался 8 тест: Используя ByteArrayOutputStream и inputStream.read из JDK

    Коротким и весьма быстрым решением будет использование IOUtils.toString из Apache Commons

    Stream Api из Java 8 показывает среднее время, а использование параллельных стримов имеет смысл только при довольно большой строки, иначе он работает очень долго (что в общем-то было ожидаемо)

  • Решение 11 лучше не использовать в принципе, так как он работает медленнее всех и не работает с Unicode,
  • Ссылка на основную публикацию
    Adblock
    detector
    ×
    ×