Eu pergunto porque estou enviando um fluxo de bytes de um processo C para Java. No lado C, o inteiro de 32 bits tem o LSB é o primeiro byte e MSB é o quarto byte.
Portanto, minha pergunta é: no lado do Java, quando lemos o byte conforme ele foi enviado do processo C, o que é endian no lado do Java?
Uma pergunta de acompanhamento: Se o endian no lado Java não for o mesmo que o enviado, como posso converter entre eles?
java
endianness
Hhafez
fonte
fonte
Respostas:
Use a ordem de bytes da rede (big endian), que é a mesma que o Java usa. Veja man htons para os diferentes tradutores em C.
fonte
Tropecei aqui via Google e obtive minha resposta que Java é big endian .
Lendo as respostas, gostaria de salientar que os bytes realmente têm uma ordem endian, embora, felizmente, se você só lidou com microprocessadores "convencionais", é improvável que os tenha encontrado como Intel, Motorola e Zilog todos concordaram na direção de mudança de seus chips UART e que MSB de um byte seria
2**7
e LSB2**0
em suas CPUs (usei a notação de potência FORTRAN para enfatizar a idade desse material :)).Eu tive esse problema com alguns dados de downlink serial de bits do ônibus espacial há mais de 20 anos, quando substituímos um hardware de interface de US $ 10 mil por um computador Mac. Há um resumo técnico da NASA publicado sobre isso há muito tempo. Eu simplesmente usei uma tabela de consulta de 256 elementos com os bits invertidos (
table[0x01]=0x80
etc.) depois que cada byte foi deslocado do fluxo de bits.fonte
Não há inteiros sem sinal em Java. Todos os inteiros são assinados e em big endian.
Parece que você está usando LSB como a parte menos significativa, não é? LSB geralmente significa byte menos significativo. Endianness não é baseado em bits, mas em bytes.
Para converter de um byte sem sinal em um inteiro Java:
Para converter de little-endian de 32 bits não assinado em byte [] para Java long (do topo da minha cabeça, não testado):
fonte
Não há como isso influenciar qualquer coisa em Java, uma vez que não há uma maneira (não-API direta) de mapear alguns bytes diretamente em um int em Java.
Cada API que faz isso ou algo semelhante define o comportamento com bastante precisão, portanto, você deve consultar a documentação dessa API.
fonte
Eu lia os bytes um por um e os combinava em um valor longo . Dessa forma, você controla o endianismo e o processo de comunicação é transparente.
fonte
Se ele se encaixa no protocolo que você usa, considere usar um DataInputStream, onde o comportamento é muito bem definido .
fonte
Java é 'Big-endian' conforme observado acima. Isso significa que o MSB de um int está à esquerda se você examinar a memória (pelo menos em uma CPU Intel). O bit de sinal também está no MSB para todos os tipos inteiros Java.
Ler um inteiro sem sinal de 4 bytes de um arquivo binário armazenado por um sistema 'Little-endian' requer um pouco de adaptação em Java. O readInt () de DataInputStream espera o formato Big-endian.
Aqui está um exemplo que lê um valor sem sinal de quatro bytes (conforme exibido pelo HexEdit como 01 00 00 00) em um inteiro com um valor de 1:
fonte
java realmente força big endian: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11
fonte
byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array();
produziu umbyte
array que é o reverso do que euC/C++
produzi. Portanto, o big endianness do Java tem efeito até mesmo nos dados em tempo de execução.