Я пишу OutputStream, только что заметил это в интерфейсе OutputStream,
public abstract void write(int b) throws IOException;
Этот вызов записывает один байт в поток, но почему он принимает целое число в качестве аргумента?
Я пишу OutputStream, только что заметил это в интерфейсе OutputStream,
public abstract void write(int b) throws IOException;
Этот вызов записывает один байт в поток, но почему он принимает целое число в качестве аргумента?
На самом деле я немного работал с байтами в последнее время, и они могут раздражать. Они преобразуются в 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 - преобразуются - я в последнее время ругался за это немного!
Итак, вы можете сигнализировать EOF:
"Обратите внимание, что read() возвращает значение int.Если вход представляет собой поток байтов, почему не читает() возвращает значение байта? Использование int в качестве возвращаемого типа позволяет read() использовать -1 чтобы указать, что он достиг конца потока".
http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html
в соответствии с javadoc для OutputStream, 24 старших бита игнорируются этой функцией. Я думаю, что метод существует для соображений совместимости: поэтому вам не нужно сначала преобразовывать в байты, и вы можете просто передать целое число.
рассматривает
Классы 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 более переносимы.
Возможно, это потому, что байты по умолчанию подписаны, а файлы хранят байты как значения без знака. Вот почему read()
возвращает int - для получения 255 вместо -1 для $FF. То же самое с write(int)
, вы не можете хранить $FF как 255 в байте.