как преобразовать считанные байты в символы какой класс для этого используется java
Ввод данных с клавиатуры
В Java используются два основных способа ввода данных с клавиатуры:
С помощью метода readLine() объекта, порожденного от класса BufferdReader из пакета java.io.
С помощью nextLine() и других методов объекта, созданного от класса Scanner из пакета java.util.
Однако в обоих случаях изначально используется System.in – объект класса InputStream, присвоенный переменной in, находящейся в классе System пакета java.lang. Данный объект выполняет функцию стандартного потока ввода, т. е. ввода с клавиатуры. (В то время как System.out – стандартный поток вывода.)
В Java объект System.in обеспечивает низкоуровневый ввод, при котором методом read() считываются байты. Например, если ввести «ab» и нажать Enter, будет прочитано три байта. В десятичном представлении значение первого байта будет соответствовать символу «a» по таблице символов, второго – символу «b», третьего – символу перехода на новую строку.
Если же ввести букву национального алфавита, которая не может кодироваться одним байтом, то каждый ее составляющий байт будет прочитан по отдельности.
Для преобразования байтов в символы, а затем в строки полученное от System.in передают в конструкторы классов-оберток. Обертки используют функционал переданного им объекта, но дополняют его своим.
Первая обертка – класс InputStreamReader, который преобразует набор байтов в символ. Класс BufferedReader буферизует ввод, обеспечивая считывание из потока ввода (клавиатура это или файл – не важно) целых строк, что делает процесс более быстрым.
Выражение BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); есть сокращенная запись от:
В случае Scanner дело обстоит попроще, так как класс может больше:
У сканера есть методы, проверяющие тип вводимых данных (hasNextInt() и т. п.). Несмотря на удобство Scanner, если надо просто считывать строки без их анализа, предпочитают использовать BufferedReader, так как он работает быстрее. В остальном выбор зависит от специфики задачи.
[Перевод] Java Best Practices. Преобразование Char в Byte и обратно
Продолжая серию статей о некоторых аспектах программирования на Java, мы коснёмся сегодня производительности String, особенно момент преобразования character в байт-последовательность и обратно в том случае, когда используется кодировка по умолчанию. В заключение мы приложим сравнение производительности между неклассическими и классическими подходами для преобразования символов в байт-последовательность и обратно.
Все изыскания базируются на проблемах в разработке крайне эффективных систем для задач в области телекоммуникации (ultra high performance production systems for the telecommunication industry).
Перед каждой из частей статьи очень рекомендуем ознакомиться с Java API для дополнительной информации и примеров кода.
Эксперименты проводились на Sony Vaio со следующими характеристиками:
ОС: openSUSE 11.1 (x86_64)
Процессор (CPU): Intel® Core(TM)2 Duo CPU T6670 @ 2.20GHz
Частота: 1,200.00 MHz
ОЗУ (RAM): 2.8 GB
Java: OpenJDK 1.6.0_0 64-Bit
Со следующими параметрами:
Одновременно тредов: 1
Количество итераций эксперимента: 1000000
Всего тестов: 100
Преобразование Char в Byte и обратно:
Задача преобразования Char в Byte и обратно широко распространена в области коммуникаций, где программист обязан обрабатывать байтовые последовательности, сериализовать String-и, реализовывать протоколы и т.д.
Для этого в Java существует набор инструментов.
Метод «getBytes(charsetName)» класса String, наверное, один из популярнейших инструментов для преобразования String в его байтовый эквивалент. Параметр charsetName указывает на кодировку String, в случае отсутствия оного метод кодирует String в последовательность байт используя стоящую в ОС по умолчанию кодировку.
Ещё одним классическим подходом к преобразованию массива символов в его байтовый эквивалент является использование класса ByteBuffer из пакета NIO (New Input Output).
Оба подхода популярны и, безусловно, достаточно просты в использовании, однако испытывают серьёзные проблемы с производительностью по сравнению с более специфическими методами. Помните: мы не конвертируем из одной кодировки в другую, для этого вы должны придерживаться «классических» подходов с использованием либо «String.getBytes (charsetName)» либо возможностей пакета NIO.
В случае ASCII мы имеем следующий код:
Массив b создаётся путём кастинга (casting) значения каждого символа в его байтовый эквивалент, при этом учитывая ASCII-диапазон (0-127) символов, каждый из которых занимает один байт.
Массив b можно преобразовать обратно в строку с помощью конструктора «new String(byte[])»:
Для кодировки по умолчанию мы можем использовать следующий код:
Каждый символ в Java занимает 2 байта, для преобразования строки в байтовый эквивалент нужно перевести каждый символ строки в его двухбайтовый эквивалент.
И обратно в строку:
Мы восстанавливаем каждый символ строки из его двухбайтового эквивалента и затем, опять же с помощью конструктора String(char[]), создаём новый объект.
Примеры использования возможностей пакета NIO для наших задач:
А теперь, как и обещали, графики.
String в byte array:
Ось абсцисс — количество тестов, ординат — количество операций в секунду для каждого теста. Что выше — то быстрее. Как и ожидалось, «String.getBytes()» и «stringToBytesUTFNIO(String)» отработали куда хуже «stringToBytesASCII(String)» и «stringToBytesUTFCustom(String)». Наши реализации, как можно увидеть, добились почти 30% увеличения количества операций в секунду.
Byte array в String:
Результаты опять же радуют. Наши собственные методы добились 15% увеличения количества операций в секунду по сравнению с «new String(byte[])» и 30% увеличения количества операций в секунду по сравнению с «bytesToStringUTFNIO(byte[])».
В качестве вывода: в том случае, если вам необходимо преобразовать байтовую последовательность в строку или обратно, при этом не требуется менять кодировки, вы можете получить замечательный выигрыш в производительности с помощью самописных методов. В итоге, наши методы добились в общем 45% ускорения по сравнению с классическими подходами.
Как преобразовать считанные байты в символы какой класс для этого используется java
Потоки ввода/вывода в Java
В чём заключается разница между IO и NIO?
Какие особенности NIO вы знаете?
Каналы (channels) – это логические (не физические) порталы, абстракции объектов более низкого уровня файловой системы (например, отображенные в памяти файлы и блокировки файлов), через которые осуществляется ввод/вывод данных, а буферы являются источниками или приёмниками этих переданных данных. При организации вывода, данные, которые необходимо отправить, помещаются в буфер, который затем передается в канал. При вводе, данные из канала помещаются в заранее предоставленный буфер.
Каналы напоминают трубопроводы, по которым эффективно транспортируются данные между буферами байтов и сущностями по ту сторону каналов. Каналы – это шлюзы, которые позволяют получить доступ к сервисам ввода/вывода операционной системы с минимальными накладными расходами, а буферы – внутренние конечные точки этих шлюзов, используемые для передачи и приема данных.
Какие существуют виды потоков ввода/вывода?
Назовите основные классы потоков ввода/вывода.
Разделяют два вида потоков ввода/вывода:
В каких пакетах расположены классы потоков ввода/вывода?
Какие подклассы класса InputStream вы знаете, для чего они предназначены?
Разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток. Класс PushbackInputStream представляет механизм «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий момент, не извлекая информации.
У класса есть дополнительный метод unread().
Какой класс позволяет читать данные из входного байтового потока в формате примитивных типов данных?
Какие подклассы класса OutputStream вы знаете, для чего они предназначены?
Какие подклассы класса Reader вы знаете, для чего они предназначены?
Какие подклассы класса Writer вы знаете, для чего они предназначены?
Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
Какие классы позволяют ускорить чтение/запись за счет использования буфера?
Какой класс предназначен для работы с элементами файловой системы?
File работает непосредственно с файлами и каталогами. Данный класс позволяет создавать новые элементы и получать информацию существующих: размер, права доступа, время и дату создания, путь к родительскому каталогу.
Какие методы класса File вы знаете?
Наиболее используемые методы класса File :
Как выбрать все элементы определенного каталога по критерию (например, с определенным расширением)?
RandomAccessFile имеет такие специфические методы как:
Какие классы поддерживают чтение и запись потоков в компрессированном формате?
Существует ли возможность перенаправить потоки стандартного ввода/вывода?
Класс System позволяет вам перенаправлять стандартный ввод, вывод и поток вывода ошибок, используя простой вызов статического метода:
Какой символ является разделителем при указании пути в файловой системе?
Что такое «абсолютный путь» и «относительный путь»?
Абсолютный (полный) путь — это путь, который указывает на одно и то же место в файловой системе, вне зависимости от текущей рабочей директории или других обстоятельств. Полный путь всегда начинается с корневого каталога.
Относительный путь представляет собой путь по отношению к текущему рабочему каталогу пользователя или активного приложения.
Что такое «символьная ссылка»?
Символьная (символическая) ссылка (также «симлинк», Symbolic link) — специальный файл в файловой системе, в котором, вместо пользовательских данных, содержится путь к файлу, который должен быть открыт при попытке обратиться к данной ссылке (файлу). Целью ссылки может быть любой объект: например, другая ссылка, файл, каталог или даже несуществующий файл (в последнем случае, при попытке открыть его, должно выдаваться сообщение об отсутствии файла).
Символьные ссылки используются для более удобной организации структуры файлов на компьютере, так как:
Как преобразовать строки в и из байтовых массивов UTF8 в Java
В Java у меня есть String, и я хочу закодировать его как байтовый массив (в UTF8 или в какой-либо другой кодировке). С другой стороны, у меня есть байтовый массив (в некоторой известной кодировке), и я хочу преобразовать его в строку Java. Как мне сделать эти преобразования?
Преобразовать из строки в байт []:
Преобразовать из байта [] в строку:
Вы должны, конечно, использовать правильное имя кодировки. В моих примерах использовались US-ASCII и UTF-8, две наиболее распространенные кодировки.
Вот решение, которое избегает выполнения поиска Charset для каждого преобразования:
Моя реализация tomcat7 принимает строки как ISO-8859-1; несмотря на тип содержимого HTTP-запроса. Следующее решение помогло мне при попытке правильно интерпретировать символы, такие как «é».
При попытке интерпретировать строку как US-ASCII, информация байта не была правильно интерпретирована.
В качестве альтернативы можно использовать StringUtils от Apache Commons.
Если у вас нестандартная кодировка, вы можете использовать getBytesUnchecked () или newString () соответственно.
Для декодирования серии байтов в обычное строковое сообщение я наконец-то начал работать с кодировкой UTF-8 с помощью этого кода:
Полный рабочий пример:
Если вы не используете расширенные символы, такие как Ä, Æ, Å, Ç, Ï, Ê и можете быть уверены, что единственными передаваемыми значениями являются первые 128 символов Unicode, то этот код также будет работать для UTF-8 и расширенного ASCII (например, CP-1252).
Я не могу комментировать, но не хочу начинать новую тему. Но это не работает. Простое путешествие в оба конца:
Мне нужен b [] один и тот же массив до и после кодирования, которого нет (это относится к первому ответу).
Преобразование между массивами байтов и шестнадцатеричными строками в Java
Узнайте, как конвертировать шестнадцатеричные строки и массивы байтов с помощью JDK и других популярных библиотек.
1. Обзор
В этом уроке мы рассмотрим различные способы преобразования массива байтов в шестнадцатеричную строку и наоборот.
Мы также поймем механизм преобразования и напишем нашу реализацию для достижения этой цели.
2. Преобразование между байтом и шестнадцатеричным
Прежде всего, давайте рассмотрим логику преобразования между байтовыми и шестнадцатеричными числами.
2.1. Байт в шестнадцатеричном формате
Например, мы можем записать 45 как 0010 1101 в двоичном формате, а шестнадцатеричный эквивалент будет “2d”:
Давайте реализуем эту простую логику в Java:
Теперь давайте разберемся в приведенном выше коде, проанализировав каждую операцию. Прежде всего, мы создали массив символов длиной 2 для хранения выходных данных:
Затем мы выделили биты более высокого порядка, сдвинув вправо 4 бита. А затем мы применили маску, чтобы изолировать 4 бита более низкого порядка. Маскировка необходима, потому что отрицательные числа внутренне представлены как дополнение двойки к положительному числу:
Затем мы преобразуем оставшиеся 4 бита в шестнадцатеричные:
Наконец, мы создаем объект String из массива char. А затем вернул этот объект в виде преобразованного шестнадцатеричного массива.
Также стоит отметить, что символ . forDigit () метод всегда возвращает строчные символы.
2.2. От шестнадцатеричного до байтового
Прежде всего, мы преобразуем каждую шестнадцатеричную цифру в двоичный эквивалент отдельно.
А затем нам нужно объединить два четырехбитовых сегмента, чтобы получить байтовый эквивалент:
Теперь давайте напишем операцию на Java:
Давайте разберемся в этом, по одной операции за раз.
Прежде всего, мы преобразовали шестнадцатеричные символы в целые числа:
Затем мы оставили самую значимую цифру сдвинутой на 4 бита. Следовательно, двоичное представление имеет нули в четырех младших значащих битах.
Затем мы добавили к нему наименее значимую цифру:
Мы проверяем возвращаемое значение и создаем исключение, если было передано недопустимое значение.
3. Преобразование между массивами байтов и шестнадцатеричными строками
3.1. Массив байтов в шестнадцатеричную строку
Нам нужно пройтись по массиву и сгенерировать шестнадцатеричную пару для каждого байта:
Как мы уже знаем, вывод всегда будет в нижнем регистре.
3.2. Шестнадцатеричная строка в массив байтов
Прежде всего, нам нужно проверить, является ли длина шестнадцатеричной строки четным числом. Это связано с тем, что шестнадцатеричная Строка с нечетной длиной приведет к неправильному представлению байтов.
Теперь мы пройдемся по массиву и преобразуем каждую шестнадцатеричную пару в байт:
4. Использование класса BigInteger
Теперь мы можем сгенерировать шестнадцатеричный String с помощью статического формата метода, определенного в классе String :
Предоставленный формат будет генерировать шестнадцатеричную строку с нулевым заполнением в нижнем регистре . Мы также можем сгенерировать строку в верхнем регистре, заменив “x” на “X”.
Теперь давайте посмотрим на шестнадцатеричное преобразование String в byte Array:
Следовательно, мы должны знать об этих деталях, прежде чем использовать класс BigInteger для преобразования.
5. Использование класса DataTypeConverter
Класс DataTypeConverter поставляется с библиотекой JAXB. Это часть стандартной библиотеки до Java 8. Начиная с Java 9, нам нужно явно добавить java.xml.bind модуль в среду выполнения.
Давайте рассмотрим реализацию с использованием класса DataTypeConverter :
Прежде чем выбрать этот подход, мы должны убедиться, что класс будет доступен во время выполнения.
6. Использование библиотеки общих кодеков Apache
7. Использование библиотеки Гуавы Google
Давайте посмотрим, как класс BaseEncoding может использоваться для кодирования и декодирования массива байтов в шестнадцатеричную строку:
8. Заключение
Не рекомендуется добавлять библиотеку, чтобы использовать только несколько служебных методов. Поэтому, если мы еще не используем внешние библиотеки, мы должны использовать описанный алгоритм. Класс DataTypeConverter – это еще один способ кодирования/декодирования между различными типами данных.