当前位置: 首页 > news >正文

Java ByteBuf解析和进制转换汇总

文章目录

  • Java ByteBuf解析和进制转换汇总
    • ByteBuf API详细介绍
      • 1. 概述
      • 2. 主要特点
      • 3. 创建方式
      • 4. 基本操作
      • 5. 内存管理
      • 6. 使用场景
      • 7. 处理大端序/小端序
      • 8. 调试工具Hex Dump
    • Java进制转换介绍
      • 1. 十进制转十六进制
      • 2. 十六进制转十进制
      • 3. 十六进制转Ascii码
      • 4. 十进制的反码
      • 5. 十六进制的反码
      • 6. 十六进制转 byte[]数组
      • 7. byte[]数组 转十六进制
      • 8. String 转 ByteBuf
      • 9. ByteBuf 转 String
      • 10. byte[] 数组 转 String
      • 11. byte b 转 Boolean
      • 12. byte b 转 String
      • 13. byte b 转 int
      • 14. byte b 转十六进制
    • 完整整合示例
      • 场景描述
      • 代码实现
    • 注意事项
    • 最后总结

Java ByteBuf解析和进制转换汇总


ByteBuf API详细介绍

1. 概述

ByteBuf 是 Netty 中对字节缓冲区的抽象,用于在网络应用中高效地处理数据读写操作。它提供了丰富的 API,让开发者可以方便地处理字节数据。

2. 主要特点

  • 性能高效 :采用直接内存操作和内存池技术,减少内存拷贝,提高数据传输效率。
  • 灵活的容量管理 :可以根据需要动态调整缓冲区容量,避免频繁的内存分配和释放。
  • 读写操作分离 :通过读索引和写索引分离设计,方便进行读写操作,避免数据覆盖等问题。
  • 丰富的 API :提供了多种读写方法,支持不同类型数据的转换和操作,方便开发者进行数据处理。

3. 创建方式

  • 堆缓冲区(Heap ByteBuf) :通过 ByteBufAllocatorheapBuffer() 方法创建,数据存储在 JVM 堆内存中,便于垃圾回收,适合频繁分配和释放的小型缓冲区。

    ByteBuf heapBuf = ByteBufAllocator.DEFAULT.heapBuffer(1024);
    
  • 直接缓冲区(Direct ByteBuf) :通过 ByteBufAllocatordirectBuffer() 方法创建,数据存储在直接内存中,减少内存拷贝,适合大数据量传输,如频繁的 I/O 操作。

    ByteBuf directBuf = ByteBufAllocator.DEFAULT.directBuffer(1024);
    
  • 复合缓冲区(Composite ByteBuf) :通过 ByteBufAllocatorcompositeBuffer() 方法创建,可以将多个 ByteBuf 合并成一个逻辑缓冲区进行操作,方便对多个缓冲区的统一管理。

    ByteBuf compositeBuf = ByteBufAllocator.DEFAULT.compositeBuffer();
    compositeBuf.addComponents(buf1, buf2, buf3);
    

4. 基本操作

  • 写操作

    • 写基本数据类型:提供了 writeXXX() 系列方法,如 writeInt()writeLong()writeBytes() 等,用于将不同类型的数据写入缓冲区。

      ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
      buf.writeInt(123);
      buf.writeLong(4567890L);
      buf.writeBytes(new byte[]{1, 2, 3, 4});
      
    • 写字符串:可以将字符串转换为字节数组后写入,或者使用 writeCharSequence() 方法指定字符编码写入。

      ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
      String str = "Hello, Netty!";
      buf.writeBytes(str.getBytes(StandardCharsets.UTF_8));
      // 或者
      buf.writeCharSequence(str, StandardCharsets.UTF_8);
      
  • 读操作

    • 读基本数据类型:提供了 readXXX() 系列方法,如 readInt()readLong()readBytes() 等,用于从缓冲区读取不同类型的数据。

      ByteBuf buf = ...; // 假设缓冲区中已写入数据
      int num = buf.readInt();
      long value = buf.readLong();
      byte[] bytes = new byte[4];
      buf.readBytes(bytes);
      
    • 读字符串:可以先读取字节数组,然后转换为字符串,或者根据长度读取指定字符数的字符串。

      ByteBuf buf = ...; // 假设缓冲区中已写入字符串数据
      byte[] bytes = new byte[buf.readableBytes()];
      buf.readBytes(bytes);
      String str = new String(bytes, StandardCharsets.UTF_8);
      // 或者
      int length = buf.readInt(); // 假设前面存储了字符串长度
      CharBuffer charBuffer = buf.readCharSequence(length, StandardCharsets.UTF_8);
      String str = charBuffer.toString();
      
  • 容量管理

    • 获取容量:使用 capacity() 方法获取缓冲区的当前容量。

      int capacity = buf.capacity();
      
    • 调整容量:使用 capacity(int newCapacity) 方法调整缓冲区容量,新容量不能小于当前写索引。

      buf.capacity(2048); // 将容量调整为 2048
      
    • 确保可写:使用 ensureWritable(int minWritableBytes) 方法确保缓冲区有足够的可写空间,如果没有,则自动调整容量。

      buf.ensureWritable(512); // 确保有 512 字节的可写空间
      
  • 索引操作

    • 获取读索引:使用 readerIndex() 方法获取当前读索引。

      int readerIndex = buf.readerIndex();
      
    • 设置读索引:使用 readerIndex(int readerIndex) 方法设置读索引,但不能超过写索引。

      buf.readerIndex(10); // 将读索引设置为 10
      
    • 获取写索引:使用 writerIndex() 方法获取当前写索引。

      int writerIndex = buf.writerIndex();
      
    • 设置写索引:使用 writerIndex(int writerIndex) 方法设置写索引,但不能小于读索引且不能超过容量。

      buf.writerIndex(20); // 将写索引设置为 20
      
    • 获取可读字节数:使用 readableBytes() 方法获取可读字节数,即写索引减去读索引。

      int readableBytes = buf.readableBytes();
      
    • 获取可写字节数:使用 writableBytes() 方法获取可写字节数,即容量减去写索引。

      int writableBytes = buf.writableBytes();
      

5. 内存管理

  • 引用计数ByteBuf 支持引用计数机制,通过 retain() 方法增加引用计数,release() 方法减少引用计数,当引用计数为 0 时,内存会被释放。

    ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
    buf.retain(); // 增加引用计数
    // 使用缓冲区
    buf.release(); // 减少引用计数,释放内存(如果引用计数为 0)
    
  • 自动释放 :在 Netty 的 ChannelPipeline 中,通常会自动管理 ByteBuf 的生命周期,在处理完成后自动释放内存,但开发者也可以手动释放以确保内存及时回收。

    try {ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();// 使用缓冲区
    } finally {buf.release(); // 确保释放内存
    }
    

6. 使用场景

  • 网络通信 :在 Netty 的网络应用中,ByteBuf 是数据传输的核心载体,用于处理客户端和服务器之间的数据读写操作。
  • 数据处理 :对二进制数据进行处理,如解析协议、构造消息等,ByteBuf 提供了方便的 API 进行数据操作。
  • 文件读写 :在进行文件读写操作时,可以使用 ByteBuf 作为缓冲区,提高读写效率。

7. 处理大端序/小端序

网络通信中需注意字节顺序(默认大端序),可通过 ByteBuf.order() 显式设置:

ByteBuf buf = Unpooled.buffer().order(ByteOrder.LITTLE_ENDIAN);
buf.writeInt(0x12345678);  // 写入小端序的 int

8. 调试工具Hex Dump

使用 Netty 的 ByteBufUtil 快速打印二进制内容:

ByteBuf buf = Unpooled.wrappedBuffer(new byte[]{0x48, 0x65});
System.out.println(ByteBufUtil.hexDump(buf));  // 输出: 4865

通过合理使用 ByteBuf API,包括ByteBufUtil工具类可以提高网络应用的性能和开发效率。在实际开发中,需要根据具体需求选择合适的创建方式和操作方法,注意内存管理以避免内存泄漏等问题。


Java进制转换介绍

概述
本文提供 Java 中进制转换、字节数组(byte[])与 Netty ByteBuf 的互操作示例,涵盖十进制、十六进制、ASCII 码、反码及基础数据类型转换等场景。
以下是一个包含 Java 技术文档进制转换结合 Bytes 数组和 ByteBuf 使用示例的 Demo

核心工具类

   import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import java.nio.charset.StandardCharsets;

1. 十进制转十六进制

public class DecimalToHex {public static String decimalToHex(int decimal) {return Integer.toHexString(decimal).toUpperCase(); // 转为大写十六进制}public static void main(String[] args) {int decimal = 255;String hex = decimalToHex(decimal);System.out.println(decimal + " 的十六进制是:" + hex);  // 输出: FF}
}

2. 十六进制转十进制

public class HexToDecimal {public static int hexToDecimal(String hex) {return Integer.parseInt(hex, 16);}public static void main(String[] args) {String hex = "FF";int decimal = hexToDecimal(hex);System.out.println(hex + " 的十进制是:" + decimal);}
}

3. 十六进制转Ascii码

public class HexToAscii {public static String hexToAscii(String hex) {StringBuilder sb = new StringBuilder();for (int i = 0; i < hex.length(); i += 2) {String str = hex.substring(i, i + 2);sb.append((char) Integer.parseInt(str, 16));}return sb.toString();}public static void main(String[] args) {String hex = "48656C6C6F";String ascii = hexToAscii(hex);System.out.println(hex + " 的Ascii码是:" + ascii);}
}

4. 十进制的反码

// demo1
public class DecimalOneComplement {public static String decimalOneComplement(int decimal) {String bin = Integer.toBinaryString(decimal);StringBuilder sb = new StringBuilder();for (char c : bin.toCharArray()) {sb.append(c == '0' ? '1' : '0');}return sb.toString();}public static void main(String[] args) {int decimal = 5;String oneComplement = decimalOneComplement(decimal);System.out.println(decimal + " 的反码是:" + oneComplement);}
}
// demo2
public static int decimalComplement(int num) {return ~num; // 按位取反
}// 示例
System.out.println(decimalComplement(5)); // 输出: -6

5. 十六进制的反码

// demo1
public class HexOneComplement {public static String hexOneComplement(String hex) {int decimal = Integer.parseInt(hex, 16);String bin = Integer.toBinaryString(decimal);StringBuilder sb = new StringBuilder();for (char c : bin.toCharArray()) {sb.append(c == '0' ? '1' : '0');}return sb.toString();}public static void main(String[] args) {String hex = "A3";String oneComplement = hexOneComplement(hex);System.out.println(hex + " 的反码是:" + oneComplement);}
}// demo2
public static String hexComplement(String hex) {int num = Integer.parseInt(hex, 16);return Integer.toHexString(~num).toUpperCase();
}// 示例
System.out.println(hexComplement("0A")); // 输出: F5

6. 十六进制转 byte[]数组

import java.util.Arrays;public class HexToByteArray {public static byte[] hexToByteArray(String hex) {int len = hex.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)+ Character.digit(hex.charAt(i + 1), 16));}return data;}public static void main(String[] args) {String hex = "48656C6C6F"; // "Hello"的十六进制byte[] bytes = hexToByteArray(hex);System.out.println("十六进制转byte数组:" + Arrays.toString(bytes));}
}

7. byte[]数组 转十六进制

import java.util.Arrays;public class ByteArrayToHex {public static String byteArrayToHex(byte[] bytes) {StringBuilder sb = new StringBuilder();for (byte b : bytes) {sb.append(String.format("%02X", b));}return sb.toString();}public static void main(String[] args) {// 示例//String hex = byteArrayToHex(new byte[]{0x48, 0x65, 0x6C, 0x6C, 0x6F}); // 输出: 48656C6C6Fbyte[] bytes = {72, 101, 108, 108, 111};String hex = byteArrayToHex(bytes);System.out.println("byte数组转十六进制:" + hex);}
}

8. String 转 ByteBuf

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;public class StringToByteBuf {public static ByteBuf stringToByteBuf(String str) {return ByteBufAllocator.DEFAULT.buffer().writeBytes(str.getBytes());}public static void main(String[] args) {String str = "Hello Netty";ByteBuf byteBuf = stringToByteBuf(str);System.out.println("String转ByteBuf:" + byteBuf);}
}

9. ByteBuf 转 String

import io.netty.buffer.ByteBuf;public class ByteBufToString {public static String byteBufToString(ByteBuf byteBuf) {byte[] bytes = new byte[byteBuf.readableBytes()];byteBuf.readBytes(bytes);return new String(bytes);}public static void main(String[] args) {ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();byteBuf.writeBytes("Hello Netty".getBytes());String str = byteBufToString(byteBuf);System.out.println("ByteBuf转String:" + str);}
}

10. byte[] 数组 转 String

public class ByteArrayToString {public static String byteArrayToString(byte[] bytes) {return new String(bytes);}public static void main(String[] args) {byte[] bytes = {72, 101, 108, 108, 111};String str = byteArrayToString(bytes);System.out.println("byte数组转String:" + str);}
}

11. byte b 转 Boolean

public class ByteToBoolean {public static Boolean byteToBoolean(byte b) {return b != 0;}public static void main(String[] args) {byte b = 1;Boolean bool = byteToBoolean(b);System.out.println("byte转Boolean:" + bool);}
}

12. byte b 转 String

public class ByteToString {public static String byteToString(byte b) {return String.valueOf(b);}public static void main(String[] args) {byte b = 65;String str = byteToString(b);System.out.println("byte转String:" + str);}
}

13. byte b 转 int

public class ByteToInt {public static int byteToInt(byte b) {// 处理符号位,转为无符号intreturn b & 0xFF;}public static void main(String[] args) {// 示例System.out.println(byteToInt((byte)0xFF)); // 输出: 255byte b = -1;int i = byteToInt(b);System.out.println("byte转int:" + i);}
}

14. byte b 转十六进制

public class ByteToHex {public static String byteToHex(byte b) {return String.format("%02X", b);}public static void main(String[] args) {// 示例//System.out.println(ByteToHex((byte)0x1A)); // 输出: 1Abyte b = 65;String hex = byteToHex(b);System.out.println("byte转十六进制:" + hex);}
}

完整整合示例

场景描述

实现一个简单的协议解析器:

  1. 接收十六进制字符串 "01FF48656C6C6F",其中 01 表示版本号,FF 为状态码,48656C6C6F 为有效载荷(“Hello” 的 ASCII)。
  2. 解析后输出版本号(十进制)、状态码的反码(十六进制)、有效载荷的字符串。

代码实现

public class ProtocolParser {public static void main(String[] args) {String hexData = "01FF48656C6C6F";ByteBuf buf = Unpooled.wrappedBuffer(hexToBytes(hexData));// 1. 读取版本号(1字节,转十进制)int version = byteToInt(buf.readByte());System.out.println("Version: " + version);  // 输出: 1// 2. 读取状态码(1字节,转十六进制反码)byte statusByte = buf.readByte();String statusHex = byteToHex(statusByte);String statusComplement = hexComplement(statusHex);System.out.println("Status Complement: " + statusComplement);  // 输出: 00// 3. 读取有效载荷(剩余字节,转字符串)byte[] payload = new byte[buf.readableBytes()];buf.readBytes(payload);String message = bytesToString(payload);System.out.println("Message: " + message);  // 输出: Hellobuf.release();  // 释放资源}// 复用之前的转换方法(hexToBytes, byteToInt, byteToHex, hexComplement, bytesToString)
}

注意事项

  1. 字节符号处理
    Java 的 byte 类型是有符号的(范围:-128~127),处理时需用 & 0xFF 转为无符号整数。
  2. 编码一致性
    Stringbyte[] 转换时需统一字符集(如 StandardCharsets.UTF_8)。
  3. 内存释放
    使用 Netty 的 ByteBuf 时,若为池化或直接内存,需手动调用 release() 防止内存泄漏。

最后总结

通过结合 Java 原生字节操作与 Netty 的 ByteBuf,可高效实现复杂协议解析、数据转换等任务。关键点包括:

  1. 内存管理:区分堆内存/直接内存,及时释放资源。
  2. 编码一致性:统一字符集避免乱码。
  3. 性能优化:利用池化缓冲区和复用对象减少 GC。
  4. 调试支持:使用 ByteBufUtil 工具快速诊断二进制数据。
http://www.xdnf.cn/news/88759.html

相关文章:

  • Spark-SQL 项目
  • Linux安装后无法启动24天
  • 数据集 | 柑橘果目标检测数据集
  • 大数据开发的基本流程
  • 基于机器学习的房租影响因素分析系统
  • 安卓模拟器绕过检测全解析:雷电、MuMu、蓝叠、逍遥、夜神与WSA完整指南
  • 3.1.1 MaterialDesign中DrawerHost使用案例
  • Kubernetes Docker 部署达梦8数据库
  • 蓝桥杯算法实战分享:C/C++ 题型解析与实战技巧
  • 明远智睿2351开发板:四核1.4G处理器——开启高效能Linux系统新纪元
  • 『不废话』之Python管理工具uv快速入门
  • 【Java】Hibernate的检索策略
  • python的深拷贝浅拷贝(copy /deepcopy )
  • 三维几何变换
  • usb2.0的硬件知识(一)
  • 查看MySql操作日志
  • 布隆过滤器的应用
  • 《Operating System Concepts》阅读笔记:p764-p766
  • 【Axure视频教程】不透明度函数
  • 以下是一个基于 ESP32 - S3 实现消息队列收发测试的 C 例程
  • crontab 定时备份 mysql 数据库
  • CF思维题(cf round 1019 div.2 b题)
  • ADS基本操作之S参数仿真
  • 如何高效优化复杂的SQL查询:以项目发布管理为例
  • Java知识大纲
  • 内存管理之文件内存映射(mmap):外存(磁盘/flash)的文件映射到应用层(跨越内核层)
  • 解析芯片低功耗设计的底层逻辑与实现方法
  • 最新项目笔记
  • Java的反射机制(曼波超易懂图文版)
  • 一洽智能硬件行业解决方案探索与实践