C 프로세스에서 Java로 바이트 스트림을 보내고 있기 때문에 묻습니다. C 쪽에서 32 비트 정수는 LSB가 첫 번째 바이트이고 MSB가 4 번째 바이트입니다.
그래서 내 질문은 : C 프로세스에서 보낸 바이트를 읽을 때 Java 측에서 Java 측에서 엔디안 이란 무엇입니까?
후속 질문 : Java 측의 엔디안이 전송 된 엔디안과 동일하지 않은 경우 어떻게 그들간에 변환 할 수 있습니까?
C 프로세스에서 Java로 바이트 스트림을 보내고 있기 때문에 묻습니다. C 쪽에서 32 비트 정수는 LSB가 첫 번째 바이트이고 MSB가 4 번째 바이트입니다.
그래서 내 질문은 : C 프로세스에서 보낸 바이트를 읽을 때 Java 측에서 Java 측에서 엔디안 이란 무엇입니까?
후속 질문 : Java 측의 엔디안이 전송 된 엔디안과 동일하지 않은 경우 어떻게 그들간에 변환 할 수 있습니까?
답변:
어쨌든 Java가 사용하는 것과 동일한 네트워크 바이트 순서 (빅 엔디안)를 사용하십시오. C의 다른 번역가는 man htons를 참조하십시오.
나는 Google을 통해 여기에서 우연히 발견했고 Java가 big endian 이라는 대답을 얻었습니다 .
응답을 읽으면서 나는 바이트가 실제로 엔디안 순서를 가지고 있음을 지적하고 싶습니다. 비록 자비 롭게도“주류”마이크로 프로세서 만 다루었다면 Intel, Motorola 및 Zilog 모두와 같이 본 적이 없을 것입니다. UART 칩의 이동 방향과 바이트의 MSB가 있고 2**7
LSB가 2**0
CPU에 있을 것이라는 데 동의했습니다 (이 항목이 얼마나 오래되었는지 강조하기 위해 FORTRAN 전원 표기법을 사용했습니다 :)).
저는 20 년 이상 전에 우리가 $ 10K 인터페이스 하드웨어를 Mac 컴퓨터로 교체했을 때 일부 Space Shuttle 비트 직렬 다운 링크 데이터로이 문제를 겪었습니다. 오래 전에 발표 된 NASA 기술 개요가 있습니다. 나는 단순히 table[0x01]=0x80
각 바이트가 비트 스트림에서 이동 한 후 비트가 반전 된 256 요소 조회 테이블을 사용했습니다 .
Java에는 부호없는 정수가 없습니다. 모든 정수는 부호가 있고 빅 엔디안입니다.
C 쪽에서 각 바이트에는 시작 부분에 LSB가 있고 왼쪽에 MSB가 있습니다.
LSB를 최하위 비트로 사용하는 것 같습니까? LSB는 일반적으로 최하위 바이트를 나타냅니다. 엔디안 은 비트 기반이 아니라 바이트 기반입니다.
부호없는 바이트에서 Java 정수로 변환하려면 다음을 수행하십시오.
int i = (int) b & 0xFF;
서명되지 않은 32 비트 little-endian in byte []에서 Java long으로 변환하려면 (테스트되지 않은 내 머리 위에서) :
long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
Java에서 일부 바이트를 직접 int로 매핑하는 (직접적인 비 API) 방법이 없기 때문에 이것이 Java의 어떤 것에 영향을 미칠 수있는 방법이 없습니다.
이를 수행하는 모든 API 또는 이와 유사한 작업은 동작을 매우 정확하게 정의하므로 해당 API의 문서를 찾아보아야합니다.
바이트를 하나씩 읽고이를 긴 값 으로 결합합니다 . 그렇게하면 엔디안을 제어 할 수 있으며 커뮤니케이션 프로세스는 투명합니다.
사용하는 프로토콜에 맞으면 동작이 매우 잘 정의 된 DataInputStream 사용을 고려하십시오 .
Java는 위에서 언급 한대로 'Big-endian'입니다. 즉, 메모리를 검사하면 int의 MSB가 왼쪽에 있습니다 (최소한 Intel CPU에서). 부호 비트는 모든 Java 정수 유형에 대한 MSB에도 있습니다.
'Little-endian'시스템이 저장 한 바이너리 파일에서 부호없는 4 바이트 정수를 읽으려면 Java에서 약간의 조정이 필요합니다. DataInputStream의 readInt ()는 Big-endian 형식을 예상합니다.
다음은 4 바이트의 부호없는 값 (HexEdit에서 01 00 00 00으로 표시됨)을 값이 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;
}
byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array();
생산 된 byte
나의 것의 반대 인 배열을 C/C++
생성합니다. 따라서 Java 의 빅 엔디안 은 런타임의 데이터에서도 적용됩니다.