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);
}
目录
相关文章
mark 和 reset
mark 和 reset
186 0
|
存储 算法 网络安全
|
Linux 安全 关系型数据库
linux设置ulimit值永久生效
小知识的积累,转自 http://hi.baidu.com/moonelf9989/blog/item/1deadf12780fa0c5c2fd789d.html linux 默认打开文件数linux 默认打开文件数为1024个,通过ulimit -a 可以查看open files 修改这个限制可以使用ulimt -SHn 65536 永久生效需要进行下面设置: 1.
12562 0
|
2天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1293 1
|
9天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
702 4
|
2天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
563 3
|
3天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费