ByteUtil
ByteUtil是Hutool中用于处理字节与数字之间转换的工具类,提供了丰富的字节数组与各种基本数据类型之间的转换方法,并支持自定义字节序(大端序/小端序)。
# 功能介绍
- 数据类型转换:支持字节数组与short、int、long、float、double等基本数据类型的相互转换
- 字节序支持:默认使用小端序,同时支持自定义大端序或小端序
- 字符串编码:提供字符串到字节数组的编码转换
- 无符号字节处理:支持无符号字节数组与BigInteger的转换
- 字节数组操作:提供字节数组连接、位统计等功能
# 核心方法
# 1. 字符串转字节数组
# toUtf8Bytes
将字符串编码为UTF-8字节数组。
String str = "Hello, Hutool!";
byte[] bytes = ByteUtil.toUtf8Bytes(str);
// 结果:[72, 101, 108, 108, 111, 44, 32, 72, 117, 116, 111, 111, 108, 33]
# toBytes
将字符串按指定字符集编码为字节数组。
String str = "Hello, Hutool!";
byte[] bytes = ByteUtil.toBytes(str, CharsetUtil.UTF_8);
# 2. 基本数据类型转字节数组
# toBytes(short)
short转字节数组,默认小端序。
short value = 1234;
byte[] bytes = ByteUtil.toBytes(value);
// 结果:[210, 4](小端序)
# toBytes(int)
int转字节数组,支持自定义字节序。
int value = 123456789;
// 小端序
byte[] littleBytes = ByteUtil.toBytes(value, ByteOrder.LITTLE_ENDIAN);
// 大端序
byte[] bigBytes = ByteUtil.toBytes(value, ByteOrder.BIG_ENDIAN);
# toBytes(long)
long转字节数组。
long value = 1234567890123L;
byte[] bytes = ByteUtil.toBytes(value);
# toBytes(float/double)
浮点型转字节数组。
float floatValue = 123.45f;
byte[] floatBytes = ByteUtil.toBytes(floatValue);
double doubleValue = 123.456;
byte[] doubleBytes = ByteUtil.toBytes(doubleValue);
# 3. 字节数组转基本数据类型
# toShort
字节数组转short。
byte[] bytes = {210, 4};
short value = ByteUtil.toShort(bytes);
// 结果:1234
# toInt
字节数组转int。
byte[] bytes = {21, 205, 90, 7};
int value = ByteUtil.toInt(bytes);
// 结果:123456789
# toLong
字节数组转long。
byte[] bytes = {101, -38, -48, -106, 91, 0, 0, 0};
long value = ByteUtil.toLong(bytes);
// 结果:1234567890123L
# toFloat/toDouble
字节数组转浮点型。
byte[] floatBytes = {64, 94, -102, -103};
float floatValue = ByteUtil.toFloat(floatBytes);
// 结果:123.45f
double doubleValue = ByteUtil.toDouble(doubleBytes);
# 4. 无符号字节处理
# toUnsignedByteArray
将BigInteger转换为无符号字节数组。
BigInteger bigInt = new BigInteger("123456789");
byte[] bytes = ByteUtil.toUnsignedByteArray(bigInt);
# fromUnsignedByteArray
无符号字节数组转BigInteger。
byte[] bytes = {7, 90, 205, 21};
BigInteger bigInt = ByteUtil.fromUnsignedByteArray(bytes);
// 结果:123456789
# 5. 字节数组操作
# concat
连接多个字节数组。
byte[] bytes1 = {1, 2, 3};
byte[] bytes2 = {4, 5, 6};
byte[] result = ByteUtil.concat(bytes1, bytes2);
// 结果:[1, 2, 3, 4, 5, 6]
# bitCount
统计字节数组中位为1的个数。
byte[] bytes = {0b00001111, 0b11110000};
int count = ByteUtil.bitCount(bytes);
// 结果:8
# 应用场景
# 1. 网络通信
在网络通信中,不同系统可能使用不同的字节序,ByteUtil可以方便地处理字节序转换:
// 接收网络数据(假设为大端序)
byte[] networkData = receiveData();
// 转换为本地字节序的int
int value = ByteUtil.toInt(networkData, ByteOrder.BIG_ENDIAN);
// 将本地数据转换为网络字节序(大端序)发送
byte[] sendData = ByteUtil.toBytes(value, ByteOrder.BIG_ENDIAN);
sendData(sendData);
# 2. 文件IO
在文件读写中,经常需要处理二进制数据:
// 从文件读取字节数据
byte[] data = FileUtil.readBytes("data.bin");
// 解析数据头(假设为4字节int表示数据长度)
int dataLength = ByteUtil.toInt(data, 0, ByteOrder.LITTLE_ENDIAN);
// 处理数据体
byte[] dataBody = Arrays.copyOfRange(data, 4, 4 + dataLength);
# 3. 序列化与反序列化
在自定义序列化框架中,ByteUtil可以用于基本数据类型的序列化:
// 序列化对象
FastByteBuffer buffer = new FastByteBuffer();
buffer.append(ByteUtil.toBytes(123)); // int类型
buffer.append(ByteUtil.toBytes(123.45)); // double类型
byte[] serializedData = buffer.toArray();
// 反序列化对象
int intValue = ByteUtil.toInt(serializedData, 0);
double doubleValue = ByteUtil.toDouble(serializedData, 4);
# 注意事项
- 字节序问题:在跨平台或网络通信时,务必注意字节序的一致性,默认使用小端序
- 数组长度:转换时要确保字节数组长度足够,否则会抛出IllegalArgumentException
- 数据类型范围:转换过程中要注意数据类型的范围,避免溢出
- null处理:字符串为null时,toBytes方法返回null
# 总结
ByteUtil提供了全面的字节操作功能,是处理二进制数据的强大工具。无论是网络通信、文件IO还是自定义序列化,都能提供简洁高效的字节转换解决方案。通过灵活使用ByteUtil,可以大大简化二进制数据处理的复杂性,提高代码的可读性和可维护性。