2009-09-10 9 views

Respuesta

9

Actualmente, he estado trabajando con bytes un poco últimamente y pueden ser molestos. Se convierten en ints a la menor provocación y no hay ninguna designación para convertir un número en byte; por ejemplo, 8l le dará un valor largo 8, pero para byte debe decir (byte) 8

Además de eso, (más o menos) siempre se almacenarán internamente como datos a menos que esté usando una matriz (y tal vez incluso entonces ... no estoy seguro).

Creo que simplemente asumen que la única razón para usar un byte es i/o donde realmente necesitas 8 bits, pero internamente esperan que siempre uses ints.

Por cierto, un byte puede realizar peor ya que siempre tiene que ser enmascarado ...

Al menos Recuerdo haber leído que hace años, podría haber cambiado por ahora.

Como ejemplo respuesta a su pregunta específica, si una función (f) tomó un byte, y que tenía dos bytes (B1 y B2), entonces:

f(b1 & b2) 

no quiere trabajar, porque b1 & b2 se convertiría a un int, y el int no se podría convertir de forma automática (pérdida de precisión). Entonces tendría que codificar:

f((byte)(b1 & b2)) 

Lo cual sería irritante.

Y no se moleste en preguntar POR QUÉ b1 & b2 up-converts - ¡Últimamente he hablado de eso un poco!

+4

amen - la manipulación de bytes en Java está llena de tales baches (generalmente el tipo que es casi imposible de capturar en el momento del diseño). y por qué en el mundo no puede el compilador descubrir que el nuevo byte [] {0x01, 0x02} es una matriz de bytes?¿Por qué tengo que escribir un nuevo byte [] {(byte) 0x01, (byte) 0x02}?

+1

Solo tiene que emitir valores que son mayores que 0x7F, porque los bytes están firmados. No hay nada irritante en eso. Es mucho mejor que tener un montón de char sin firmar/firmado. Use IDE, verificará la seguridad del tipo y hará el yeso por usted. La operación de máscara es una instrucción, no afecta el rendimiento. –

6

según javadoc para OutputStream, esta función no tiene en cuenta los 24 bits de orden superior. Creo que el método existe por razones de compatibilidad: por lo tanto, no es necesario convertirlo primero en bytes y simplemente puede pasar un número entero.

respecto

+2

compatibilidad con lo que, sin embargo? – skaffman

+1

bueno, la compatibilidad podría ser una palabra incorrecta ... llamémoslo simplicidad o amigable con los programadores; o) – Atmocreations

+0

La discontinuidad entre 'write (int)' y 'write (byte [])' es bastante llamativa, aunque , especialmente cuando ve que la implementación predeterminada de 'write (byte [])' solo llama a 'write (int)' en un bucle. – skaffman

24

Así que puede ser señal de EOF:.

"Nótese que leer() devuelve un valor int Si la entrada es una secuencia de bytes, ¿por qué no lee() devuelve un valor de byte "Usar un int como un tipo de retorno permite a read() usar -1 para indicar que ha llegado al final de la transmisión".

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

+0

mhm, buen punto – Atmocreations

+7

Entonces, si escribes (-1), ¿qué sucede? ¿Se cierra la secuencia? :-) – Ken

+0

No. Terminas escribiendo extraños caracteres Unicode en la transmisión de salida. Pero si hubiera una secuencia de recepción para su escritura (-1), creo que señalaría el final del flujo a esa secuencia. Hay 3 posibilidades de transmisión: las primeras 2 transfieren un número específico de bytes: escritura (byte [] b, int off, int len) y escritura (byte b). La tercera opción le permite transferir un número indeterminado de bytes usando int. Es por eso que se usa int. – sfish

2

Las clases de Java iostream han sido una parte de Java desde el 1.0. Estas clases solo tratan con datos de 8 bits. Mi suposición es que la interfaz fue diseñada así para que el método de escritura (int b) fuera llamado para los valores int, short, byte y char. Todos estos son promovidos a un int. De hecho, dado que la mayoría de las JVM se ejecutan en máquinas de 32 bits, la primitiva int es el tipo más eficiente para tratar. El compilador puede almacenar tipos como bytes utilizando 32 bits de todos modos. Curiosamente, byte [] realmente se almacena como una secuencia de bytes de 8 bits. Esto tiene sentido ya que una matriz puede ser bastante grande. Sin embargo, en el caso de valores primitivos únicos, como int o byte, el último espacio ocupado en tiempo de ejecución realmente no importa siempre que el comportamiento sea coherente con la especificación.

Más de fondo:

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

El supuesto para las clases iostream es que la persona que llama en realidad sólo se preocupa por 8 bits más bajos de los datos incluso cuando pasan de un int. Esto está bien siempre y cuando la persona que llama sepa que realmente está tratando con bytes, pero se convierte en un problema cuando los datos subyacentes son realmente texto que usa alguna otra codificación de caracteres como Unicode de múltiples bytes. Esta es la razón por la cual las clases Reader se introdujeron mucho tiempo atrás con Java 1.1. Si le importan los datos de texto y el rendimiento, las clases de IOStream son más rápidas, pero las clases de Reader son más portátiles.

2

Tal vez sea porque los bytes están firmados por defecto, y los archivos almacenan los bytes como valores sin firmar. Es por eso que read() devuelve un int - para dar 255 en lugar de -1 para $ FF. Lo mismo con write(int), no puede almacenar $ FF como 255 en un byte.

Cuestiones relacionadas