Pergunta

Eu pergunto porque eu estou enviando um fluxo de bytes de um processo de C para Java. No lado do C o número inteiro de 32 bit tem o bit menos significativo é o primeiro byte e MSB é o quarto byte.

Então, minha pergunta é: No lado do Java quando lemos o byte como foi enviado a partir do processo C, o que é endian no lado do Java?

A follow-up questão: Se o endian no lado do Java não é o mesmo que o enviado, como posso converter entre eles

?
Foi útil?

Solução

Use a ordem de bytes da rede (big endian), que é o mesmo que Java usa de qualquer maneira. Veja homem htons para os diferentes tradutores em C.

Outras dicas

Eu tropecei aqui via Google e tenho a minha resposta de que Java é grande endian.

Leitura através das respostas que eu gostaria de salientar que bytes têm de fato uma ordem endian, embora felizmente, se você lidou apenas com microprocessadores "mainstream" é improvável que você já encontrei-o como Intel, Motorola, e Zilog todos concordaram com a direção de desvio de seus chips UART e que MSB de um byte seria 2 ** 7 e LSB seria 2 ** 0 em suas CPUs (eu usei a notação poder Fortran para enfatizar quantos anos este material é: )).

Eu corri para este problema com alguns Space Shuttle bit de dados downlink de série mais de 20 anos atrás, quando nós substituímos um hardware interface de $ 10K com um computador Mac. Há uma breve NASA Tecnologia publicado sobre isso há muito tempo. I simplesmente utilizado um elemento 256 tabela de consulta com os bits invertidos (tabela [0x01] = 0x80 etc) após cada byte foi deslocado a partir do fluxo de bits.

Não há inteiros sem sinal em Java. Todos os números inteiros são assinados e em big endian.

No lado do C a cada byte tem tne LSB no início está à esquerda e o MSB no final.

Parece que você está usando LSB como bit menos significativo, não é? LSB geralmente significa byte menos significativo. Endianness não é pouco baseada mas byte base.

Para converter de byte não assinado para um inteiro Java:

int i = (int) b & 0xFF;

Para converter de 32 bits sem sinal little-endian em byte [] para Java longa (a partir do topo da minha cabeça, não testada):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;

Não há nenhuma maneira isso poderia influenciar qualquer coisa em Java, uma vez que não há nenhuma maneira (não-API direta) para mapear alguns bytes diretamente em um int em Java.

Cada API que faz isso ou algo define semelhantes o comportamento muito precisamente, então você deve olhar a documentação de que API.

Eu lia os bytes, um a um, e combiná-los em um longo valor. Dessa forma, você controlar a ordenação, e o processo de comunicação é transparente.

Se ele se encaixa o protocolo que você usa, considere usar um DataInputStream, onde o comportamento é muito bem definida .

Java é 'Big-endian' como mencionado acima. Isso significa que o MSB de um int é do lado esquerdo se você examinar a memória (em um Intel CPU, pelo menos). O bit de sinal também está no MSB para todos os tipos inteiros Java.
Lendo um inteiro não assinado de 4 bytes de um arquivo binário armazenado por um sistema de 'Little-endian' leva um pouco de adaptação em Java. readInt de DataInputStream () espera formato big-endian.
Aqui está um exemplo que lê um valor não assinado de quatro bytes (como exibido por HexEdit como 01 00 00 00) em um número inteiro com um valor de 1:

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top