2.1 ByteBuffer 正确使用姿势

简介: 2.1 ByteBuffer 正确使用姿势
  • 向 buffer 写入数据,例如调用 channel.read(buffer)
  • 调用 flip() 切换至读模式
  • 从 buffer 读取数据,例如调用 buffer.get()
  • 调用 clear() 或 compact() 切换至写模式
  • 重复 1~4 步骤

image.pngimage.pngimage.png

public class ByteBufferUtil { private static final char[] BYTE2CHAR = new char[256]; private static final char[] HEXDUMP_TABLE = new char[256 * 4]; private static final String[] HEXPADDING = new String[16]; private static final String[] HEXDUMP_ROWPREFIXES = new String[65536 >>> 4]; private static final String[] BYTE2HEX = new String[256]; private static final String[] BYTEPADDING = new String[16];



image.png

static {
    final char[] DIGITS = "0123456789abcdef".toCharArray();
    for (int i = 0; i < 256; i++) {
        HEXDUMP_TABLE[i << 1] = DIGITS[i >>> 4 & 0x0F];
        HEXDUMP_TABLE[(i << 1) + 1] = DIGITS[i & 0x0F];
    }
    int i;
    // Generate the lookup table for hex dump paddings
    for (i = 0; i < HEXPADDING.length; i++) {
        int padding = HEXPADDING.length - i;
        StringBuilder buf = new StringBuilder(padding * 3);
        for (int j = 0; j < padding; j++) {
            buf.append("   ");
        }
        HEXPADDING[i] = buf.toString();
    }
    // Generate the lookup table for the start-offset header in each row (up to 64KiB).
    for (i = 0; i < HEXDUMP_ROWPREFIXES.length; i++) {
        StringBuilder buf = new StringBuilder(12);
        buf.append(NEWLINE);
        buf.append(Long.toHexString(i << 4 & 0xFFFFFFFFL | 0x100000000L));
        buf.setCharAt(buf.length() - 9, '|');
        buf.append('|');
        HEXDUMP_ROWPREFIXES[i] = buf.toString();
    }
    // Generate the lookup table for byte-to-hex-dump conversion
    for (i = 0; i < BYTE2HEX.length; i++) {
        BYTE2HEX[i] = ' ' + StringUtil.byteToHexStringPadded(i);
    }
    // Generate the lookup table for byte dump paddings
    for (i = 0; i < BYTEPADDING.length; i++) {
        int padding = BYTEPADDING.length - i;
        StringBuilder buf = new StringBuilder(padding);
        for (int j = 0; j < padding; j++) {
            buf.append(' ');
        }
        BYTEPADDING[i] = buf.toString();
    }
    // Generate the lookup table for byte-to-char conversion
    for (i = 0; i < BYTE2CHAR.length; i++) {
        if (i <= 0x1f || i >= 0x7f) {
            BYTE2CHAR[i] = '.';
        } else {
            BYTE2CHAR[i] = (char) i;
        }
    }
}
/**
 * 打印所有内容
 * @param buffer
 */
public static void debugAll(ByteBuffer buffer) {
    int oldlimit = buffer.limit();
    buffer.limit(buffer.capacity());
    StringBuilder origin = new StringBuilder(256);
    appendPrettyHexDump(origin, buffer, 0, buffer.capacity());
    System.out.println("+--------+-------------------- all ------------------------+----------------+");
    System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), oldlimit);
    System.out.println(origin);
    buffer.limit(oldlimit);
}
/**
 * 打印可读取内容
 * @param buffer
 */
public static void debugRead(ByteBuffer buffer) {
    StringBuilder builder = new StringBuilder(256);
    appendPrettyHexDump(builder, buffer, buffer.position(), buffer.limit() - buffer.position());
    System.out.println("+--------+-------------------- read -----------------------+----------------+");
    System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), buffer.limit());
    System.out.println(builder);
}
private static void appendPrettyHexDump(StringBuilder dump, ByteBuffer buf, int offset, int length) {
    if (isOutOfBounds(offset, length, buf.capacity())) {
        throw new IndexOutOfBoundsException(
                "expected: " + "0 <= offset(" + offset + ") <= offset + length(" + length
                        + ") <= " + "buf.capacity(" + buf.capacity() + ')');
    }
    if (length == 0) {
        return;
    }
    dump.append(
            "         +-------------------------------------------------+" +
                    NEWLINE + "         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |" +
                    NEWLINE + "+--------+-------------------------------------------------+----------------+");
    final int startIndex = offset;
    final int fullRows = length >>> 4;
    final int remainder = length & 0xF;
    // Dump the rows which have 16 bytes.
    for (int row = 0; row < fullRows; row++) {
        int rowStartIndex = (row << 4) + startIndex;
        // Per-row prefix.
        appendHexDumpRowPrefix(dump, row, rowStartIndex);
        // Hex dump
        int rowEndIndex = rowStartIndex + 16;
        for (int j = rowStartIndex; j < rowEndIndex; j++) {
            dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);
        }
        dump.append(" |");
        // ASCII dump
        for (int j = rowStartIndex; j < rowEndIndex; j++) {
            dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);
        }
        dump.append('|');
    }
    // Dump the last row which has less than 16 bytes.
    if (remainder != 0) {
        int rowStartIndex = (fullRows << 4) + startIndex;
        appendHexDumpRowPrefix(dump, fullRows, rowStartIndex);
        // Hex dump
        int rowEndIndex = rowStartIndex + remainder;
        for (int j = rowStartIndex; j < rowEndIndex; j++) {
            dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);
        }
        dump.append(HEXPADDING[remainder]);
        dump.append(" |");
        // Ascii dump
        for (int j = rowStartIndex; j < rowEndIndex; j++) {
            dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);
        }
        dump.append(BYTEPADDING[remainder]);
        dump.append('|');
    }
    dump.append(NEWLINE +
            "+--------+-------------------------------------------------+----------------+");
}
private static void appendHexDumpRowPrefix(StringBuilder dump, int row, int rowStartIndex) {
    if (row < HEXDUMP_ROWPREFIXES.length) {
        dump.append(HEXDUMP_ROWPREFIXES[row]);
    } else {
        dump.append(NEWLINE);
        dump.append(Long.toHexString(rowStartIndex & 0xFFFFFFFFL | 0x100000000L));
        dump.setCharAt(dump.length() - 9, '|');
        dump.append('|');
    }
}
public static short getUnsignedByte(ByteBuffer buffer, int index) {
    return (short) (buffer.get(index) & 0xFF);
}
目录
相关文章
|
2月前
|
Linux API iOS开发
Ollama 保姆级实战教程:本地离线部署开源大模型,Windows/macOS/Linux 全平台安装、API 调试与故障排坑详解
Ollama降低了本地运行开源大模型的门槛,普通个人电脑就可以离线运行Qwen、DeepSeek‑R1、Llama等主流开源模型,数据保存在本地,保障隐私安全。整套工具由图形界面、终端命令、REST API三部分组成,支持Windows、macOS、Linux三大平台。
703 0
|
2月前
|
人工智能 运维 数据可视化
最新版阿里云百炼大模型服务平台功能介绍
大模型应用落地过程中,开发者往往需要面对模型选型、接口对接、私有知识库构建、智能体编排、模型微调优化、效果评测等一系列复杂工作。如果分别使用不同工具完成各个环节,会造成工具链割裂、密钥繁多、数据不互通、运维成本居高不下等问题。百炼作为一站式大模型服务平台,整合模型推理、多模态能力、智能体开发、RAG知识库、模型调优评测、MCP插件托管、CLI命令行工具、多套订阅计费体系,把大模型应用开发全链路能力收敛到统一平台,无论是个人开发者快速验证原型,还是企业搭建生产级AI业务,都可以获得完整的技术支撑。
407 0
|
5月前
|
数据采集 人工智能 供应链
2026企业如何应用数据中台?落地实战:选型、案例与避坑指南
本文剖析数据中台本质:非“大仓库”,而是覆盖采集、整合、治理、服务的全链路数据服务体系。结合阿里OneData方法论与瓴羊Dataphin实践,详解其破解数据孤岛、实时分析、治理缺失三大痛点的价值,梳理零售、金融、制造等行业落地案例,并提供选型指南与避坑原则,助力企业实现数据驱动增长。(239字)
|
5月前
|
编解码 监控 算法
【专利技术】一种可溯源的高效鲁棒视频水印技术
合肥高维数据与中科大联合研发新型视频水印技术,首创空间域高效嵌入+多帧鲁棒提取方案,在PSNR≈49dB(视觉无感)前提下,实现单帧50–130ms实时处理,压缩/转码/翻拍后提取准确率超90%,兼顾高效率、强鲁棒与广适配,为安防、政务、教育、广电等全场景数字内容提供可溯源版权保护。(239字)
485 2
|
机器学习/深度学习 编解码 文字识别
医疗票据OCR图像预处理:印章干扰过滤方案与代码实现
医疗票据OCR技术能自动提取票据中的关键信息,但在实际应用中面临多重挑战。首先,票据版式多样,不同医院、地区的格式差异大,需借助动态模板匹配技术来应对。其次,图像质量参差不齐,存在褶皱、模糊、倾斜、印章遮挡等问题,常通过超分辨率重建和图像修复算法处理。此外,手写体识别、复杂业务逻辑理解(如医疗术语和费用规则)以及数据安全与隐私合规要求也是技术难点。 为应对这些挑战,快瞳系统采用“OCR基础识别 + NLP语义修正”的混合架构,并结合深度学习模型(如CRNN、Transformer)来提升准确率和泛化能力。该技术能显著提升医保报销、保险理赔等场景的效率,是推动医疗信息数字化管理的重要工具。
1190 5
| 和 || 的区别详解及应用场景对比
本文详细解析了编程中“|”与“||”的区别:|为按位或运算,适用于数值计算;||为逻辑或运算,用于布尔判断,且具有短路特性(左表达式为真时右表达式不计算)。结合实例说明两者在条件判断、位操作等场景的应用,强调正确使用对程序效率的重要性。附面试资料链接供深入学习。
774 0
|
JSON API 开发者
淘宝平台获取商品视频 API 接口技术指南
本文介绍如何通过淘宝开放平台API获取商品视频信息,涵盖开发者账号注册、应用创建、API调用流程及Python代码示例,助您快速实现商品视频数据的提取与集成,适用于数据分析与第三方应用开发。
2304 0
|
JSON API 数据格式
1688 API接口的应用场景介绍
1688是阿里巴巴旗下B2B批发平台,其API支持商品、订单、库存、价格及物流数据的自动化获取与同步,助力企业实现系统集成与数据驱动运营。通过RESTful接口,结合OAuth认证,开发者可高效构建电商、ERP、BI等应用,提升供应链效率。
|
人工智能 自然语言处理 安全
如何让 AI 工具更懂你,更听话?
你是否也曾被AI“气到吐血”?明明说的是A,AI却给了B?别沮丧,2025年的AI也需要“正确沟通”。本文教你五大提示技巧:动态提示、多模态输入、Few-shot示例、任务分解与安全边界,让AI从“人工智障”变身“贴心助手”。学会“说AI的语言”,释放创造力,提升效率,开启智能生活新时代!
2468 0