Подтвердить что ты не робот

Почему Java OutputStream.write() принимает целочисленные, но записывает байты

Я пишу OutputStream, только что заметил это в интерфейсе OutputStream,

   public abstract void write(int b) throws IOException;

Этот вызов записывает один байт в поток, но почему он принимает целое число в качестве аргумента?

4b9b3361

Ответ 1

На самом деле я немного работал с байтами в последнее время, и они могут раздражать. Они преобразуются в ints при малейшей провокации и нет обозначения, чтобы превратить число в байт - например, 8l даст вам длинное значение 8, но для байта вы должны сказать (байт) 8

Кроме того, они будут (почти всегда) храниться внутри как ints, если вы не используете массив (и, возможно, даже тогда.. не уверены).

Я думаю, что они просто полагают, что единственной причиной использования байта является i/o, где вам действительно нужны 8 бит, но внутренне они ожидают, что вы всегда будете использовать ints.

Кстати, байт может работать хуже, поскольку он всегда должен быть замаскирован...

По крайней мере, я помню, что читал это много лет назад, возможно, уже изменился.

В качестве примера ответом на ваш конкретный вопрос, если функция (f) взяла байт, и у вас было два байта (b1 и b2), тогда:

f(b1 & b2)

не будет работать, потому что b1 и b2 будут преобразовываться вверх в int, и int не может быть преобразован автоматически (потеря точности). Таким образом, вам нужно будет ввести код:

f( (byte)(b1 & b2) )

Что будет раздражать.

И не беспокойтесь, спрашивайте, ПОЧЕМУ b1 и b2 - преобразуются - я в последнее время ругался за это немного!

Ответ 2

Итак, вы можете сигнализировать EOF:

"Обратите внимание, что read() возвращает значение int.Если вход представляет собой поток байтов, почему не читает() возвращает значение байта? Использование int в качестве возвращаемого типа позволяет read() использовать -1 чтобы указать, что он достиг конца потока".

http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html

Ответ 3

в соответствии с javadoc для OutputStream, 24 старших бита игнорируются этой функцией. Я думаю, что метод существует для соображений совместимости: поэтому вам не нужно сначала преобразовывать в байты, и вы можете просто передать целое число.

рассматривает

Ответ 4

Классы Java IOStream являются частью Java начиная с версии 1.0. Эти классы занимаются только 8-битными данными. Я предполагаю, что интерфейс был спроектирован так, чтобы один метод write (int b) вызывался для значений int, short, byte и char. Все они продвигаются до цели. Фактически, поскольку большинство JVM работают на 32-битных машинах, примитив int является наиболее эффективным типом, с которым приходится иметь дело. В любом случае компилятор может хранить такие типы, как байты, используя 32 бита. Интересно, что байт [] действительно хранится в виде последовательности из 8 бит байтов. Это имеет смысл, так как массив может быть довольно большим. Однако в случае одиночных примитивных значений, таких как int или byte, конечное пространство, занимаемое во время выполнения, на самом деле не имеет значения, если поведение соответствует спецификации.

Больше фона:

http://www.java-samples.com/showtutorial.php?tutorialid=260

Предположение для классов IOStream заключается в том, что вызывающий абонент действительно заботится о минимальных 8 битах данных даже при передаче в int. Это нормально, поскольку вызывающий абонент знает, что он действительно имеет дело с байтами, но становится проблемой, когда базовые данные - это действительно текст, который использует некоторую другую кодировку символов, такую ​​как многобайтовый Unicode. Вот почему классы Reader были введены обратно с Java 1.1. Если вам нужны текстовые данные и производительность, классы IOStream работают быстрее, но классы Reader более переносимы.

Ответ 5

Возможно, это потому, что байты по умолчанию подписаны, а файлы хранят байты как значения без знака. Вот почему read() возвращает int - для получения 255 вместо -1 для $FF. То же самое с write(int), вы не можете хранить $FF как 255 в байте.