关于little endian和big endian的问题
导入:是因为一个小 demo中,录音一段内容传到后台播放都是嘈杂音,所引发的问题和学习
笼统的解释是:CPU处理器存储数据的字节顺序,分为little endian 和 big endian
以下来详细的学习:
- 首先来学习一下:
1、高/低地址端:
栈底 栈 栈顶
高地址端 低地址端
2、高/低位字节
在十进制中:左边是高位,右边是低位,其他进制也一样
例如:0x123678 由高到低的次序为 0x12 0x36 0x78
3、字节序
即字节的顺序,也就是说大于一个字节类型的数据在内存中的存放顺序
通常分为两种:大端字节序和小端字节序
little endian:低位字节摆放在内存地址的低地址端,高位字节摆放在内存地址的高地址端
big endian:高位字节摆放在内存地址的低地址端,低位字节摆放在内存地址的高地址端
网络字节序,即TCP/IP各层协议采用的是big endian,还有其他字节序,比如middle endian等
下面来看一下不同字节序的存放位置:int i = 0x1234
(int类型四个字节,用buf[4] 表示内存地址)
低地址端 | 栈顶 | 栈 | 栈底 | 高地址端 |
---|---|---|---|---|
little endian | buf[0] | buf[1] | buf[2] | buf[3] |
0x4 | 0x3 | 0x2 | 0x1 | |
big endian | buf[0] | buf[1] | buf[2] | buf[3] |
0x1 | 0x2 | 0x3 | 0x4 |
知道了如何存放,就该学习一下,两种不同存放方式,怎么转换呢?
例如1:
short[] buffer = new short[bufferSize];
while (isRecording) {
int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
dos.writeShort(Short.reverseBytes(buffer[i])); //由big endian转little endian
}
dos.write(buffer,0,bufferReadResult);
}
例如2:
InputStream inputStream = new FileInputStream(file);
byte[] buf = new byte[(int) file.length()];
inputStream.read(buf);
inputStream.close();
short[] bufshort = toShortArray(buf); //先将byte[] 转成short[],因为录音存的short
byte[] bufbyte = new byte[buf.length]; //新建byte[],存储转化后的字节
ByteBuffer byteBuffer = ByteBuffer.wrap(bufbyte).order(ByteOrder.LITTLE_ENDIAN); //利用ByteBuffer转化
for (int i = 0; i <bufshort.length ; i++) {
byteBuffer.putShort(bufshort[i]); //将每一个short经过byteBuffer处理
}
//对处理后的字节数组编码生成字符串
return Base64.encodeToString(bufbyte, Base64.NO_WRAP);
参考:
https://stackoverflow.com/questions/4398731/java-little-endian-order