Почему Java OutputStream.write () принимает целое число, но записывает байты - PullRequest
30 голосов
/ 11 сентября 2009

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

   public abstract void write(int b) throws IOException;

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

Ответы [ 5 ]

26 голосов
/ 11 сентября 2009

Так что вы можете подать сигнал EOF:

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

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

10 голосов
/ 11 сентября 2009

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

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

Я думаю, они просто в значительной степени предполагают, что единственная причина использования байта - это ввод-вывод, когда вам действительно нужно 8 бит, но внутри они ожидают, что вы всегда будете использовать целые числа.

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

По крайней мере, я помню, как читал, что годы назад могли бы измениться.

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

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы раздражать.

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

7 голосов
/ 11 сентября 2009

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

regards

3 голосов
/ 11 сентября 2009

Классы Java IOStream были частью Java с 1.0. Эти классы имеют дело только с 8-битными данными. Я предполагаю, что интерфейс был спроектирован таким образом, чтобы метод 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. Это нормально, пока вызывающий объект знает, что он действительно имеет дело с байтами, но это становится проблемой, когда базовые данные действительно представляют собой текст, который использует некоторую другую кодировку символов, такую ​​как многобайтовый Unicode. Вот почему классы Reader были введены еще в Java 1.1. Если вы заботитесь о текстовых данных и производительности, классы IOStream работают быстрее, но классы Reader более переносимы.

2 голосов
/ 11 сентября 2009

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

...