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

Я добавил решение с потоком из jcollado в мой модуль Python easyprocess .

Установка:

pip install easyprocess

Пример:

from easyprocess import Proc

# shell is not supported!
stdout=Proc('ping localhost').call(timeout=1.5).stdout
print stdout

30
задан Jonik 11 September 2009 в 07:36
поделиться

5 ответов

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

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

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

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

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

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

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы вас раздражало.

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

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

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

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

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы вас раздражало.

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

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

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

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

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы вас раздражало.

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

и у вас было два байта (b1 и b2), тогда:

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы вас раздражало.

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

и у вас было два байта (b1 и b2), тогда:

f(b1 & b2)

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

f( (byte)(b1 & b2) )

Что бы вас раздражало.

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

10
ответ дан 28 November 2019 в 00:01
поделиться

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

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

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

26
ответ дан 28 November 2019 в 00:01
поделиться

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

касательно

7
ответ дан 28 November 2019 в 00:01
поделиться

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

Дополнительная информация:

http: // www .java-образцы. com / showtutorial.php? tutorialid = 260

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

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

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

3
ответ дан 28 November 2019 в 00:01
поделиться

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

2
ответ дан 28 November 2019 в 00:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: