Почему Java OutputStream.write() Принимает целое число, но записывает байты
-
05-07-2019 - |
Вопрос
Я пишу OutputStream, только что заметил это в интерфейсе OutputStream,
public abstract void write(int b) throws IOException;
Этот вызов записывает один байт в поток, но почему он принимает integer в качестве аргумента?
Решение
На самом деле, в последнее время я немного работал с байтами, и они могут раздражать. Они преобразуют в целые числа при малейшей провокации, и нет никакого обозначения, чтобы превратить число в байт - например, 8l даст вам длинное значение 8, но для байта вы должны сказать (байт) 8
Кроме того, они (в значительной степени) всегда будут храниться внутри как целые, если вы не используете массив (и, может быть, даже тогда ... не уверен).
Я думаю, они просто в значительной степени предполагают, что единственная причина использования байта - это ввод-вывод, когда вам действительно нужно 8 бит, но внутри они ожидают, что вы всегда будете использовать целые числа.
Кстати, байт может работать хуже, поскольку его всегда нужно маскировать ...
По крайней мере, я помню, как читал, что годы назад могли бы измениться.
В качестве примера ответа на конкретный вопрос: если функция (f) заняла байт, а у вас было два байта (b1 и b2), то:
f(b1 & b2)
не сработает, потому что b1 & amp; b2 преобразуется с повышением в int, а int не может быть преобразовано с понижением автоматически (потеря точности). Так что вам придется кодировать:
f( (byte)(b1 & b2) )
Что бы раздражать.
И даже не спрашивайте, ПОЧЕМУ b1 & amp; b2 up-новообращенные - в последнее время я сам немного ругал это!
Другие советы
Так что вы можете сигнализировать EOF:
" Обратите внимание, что read () возвращает значение типа int. Если входные данные представляют собой поток байтов, почему read () не возвращает байтовое значение? Использование int в качестве возвращаемого типа позволяет read () использовать -1, чтобы указать, что он достиг конца потока. & Quot;
http://java.sun.com/docs/ книги / учебник / важно / ю / bytestreams.html
согласно javadoc для Выходной поток, 24 бита старшего порядка игнорируются этой функцией.я думаю, что этот метод существует по соображениям совместимости:поэтому вам не нужно сначала преобразовывать в байт, и вы можете просто передать целое число.
с уважением
Классы Java IOStream являются частью Java начиная с версии 1.0.Эти классы имеют дело только с 8-битными данными.Я предполагаю, что интерфейс был разработан таким образом, чтобы метод one write (int b) вызывался для значений int, short, byte и char.Все они повышаются до значения int.Фактически, поскольку большинство JVM работают на 32-разрядных машинах, примитив int является наиболее эффективным типом для работы.Компилятор в любом случае может свободно хранить такие типы, как байты, используя 32 бита.Интересно, что byte[] на самом деле хранится в виде последовательности из 8 битных байтов.Это имеет смысл, поскольку массив может быть довольно большим.Однако в случае отдельных примитивных значений, таких как int или byte, максимальное пространство, занимаемое во время выполнения, на самом деле не имеет значения, если поведение соответствует спецификации.
Дополнительная информация:
http://www.java-samples.com/showtutorial.php?tutorialid=260
Предположение для классов IOStream состоит в том, что вызывающий объект действительно заботится только о младших 8 битах данных, даже при передаче в int.Это нормально, пока вызывающий объект знает, что он действительно имеет дело с байтами, но это становится проблемой, когда базовыми данными на самом деле является текст, использующий какую-либо другую кодировку символов, такую как многобайтовый Юникод.Вот почему классы Reader были введены еще в Java 1.1.Если вы заботитесь о текстовых данных и производительности, классы IOStream работают быстрее, но классы Reader более переносимы.
Возможно, это связано с тем, что байты подписаны по умолчанию, а файлы хранят байты как значения без знака. Вот почему read ()
возвращает целое число - 255 вместо -1 для $ FF. То же самое с write (int)
, вы не можете хранить $ FF как 255 в байте.