对于这个 Java ByteBuffer 的行为有解释吗?

2024-01-28

我需要将数值转换为字节数组。例如,要将 long 转换为字节数组,我有以下方法:

public static byte[] longToBytes(long l) {
  ByteBuffer buff = ByteBuffer.allocate(8);

  buff.order(ByteOrder.BIG_ENDIAN);

  buff.putLong(l);

  return buff.array();
}

这非常简单 - 取一个很长的值,分配一个可以容纳它的数组,然后把它扔进去。不论其价值如何l是的,我将得到一个 8 字节数组,然后我可以按预期处理和使用它。就我而言,我正在创建自定义二进制格式,然后通过网络传输它。

当我使用值 773450364 调用此方法时,我得到一个数组[0 0 0 0 46 25 -22 124]后退。我有代码也可以将字节数组转换回其数值:

public static Long bytesToLong(byte[] aBytes, int start) {
  byte[] b = new byte[8];

  b[0] = aBytes[start + 0];
  b[1] = aBytes[start + 1];
  b[2] = aBytes[start + 2];
  b[3] = aBytes[start + 3];
  b[4] = aBytes[start + 4];
  b[5] = aBytes[start + 5];
  b[6] = aBytes[start + 6];
  b[7] = aBytes[start + 7];

  ByteBuffer buf = ByteBuffer.wrap(b);
 return buf.getLong();
}

当我将数组从另一个方法传递回此方法时,我得到 773450364,这是正确的。

现在,我通过 TCP 将该数组传输到另一个 Java 客户端。的文档java.io.InputStream.read()方法说它返回一个int0 到 255 之间的值,除非到达流末尾并返回 -1。但是,当我使用它填充字节数组时,我继续在接收端获取负值。我怀疑这与溢出有关(值 255 无法放入 Java 字节中,因此当我将其放入字节数组中时,它会溢出并变为负数)。

这让我想到了我的问题。负数的存在让我担心。现在,我正在开发应用程序的 Java 端,其中字节介于 -128 和 127 之间(包含 -128 和 127)。另一个端点可能是 C、C++、Python、Java、C#...谁知道呢。我不确定某些字节数组中负值的存在将如何影响处理。除了记录此行为之外,我可以/应该做些什么来让我自己和未来的开发人员更轻松地在这个系统上工作,特别是在不是用 Java 编写的端点中?


A byte在Java中是用8位来表示的二进制补码 http://en.wikipedia.org/wiki/Two%27s_complement格式。如果你有一个int其范围为 128 - 255,然后将其投射到byte,那么它将成为一个byte为负值(-1 到 -128 之间)。

读取一个字节后,必须检查它是否为-1在你把它投射到之前byte。该方法返回的原因是int而不是一个byte是允许您在将其转换为流之前检查流结束byte.

另一件事:你为什么要复制aBytes数组在你的bytesToLong方法?您可以大大简化该方法并保存不必要的副本:

public static Long bytesToLong(byte[] aBytes, int start) {
    return ByteBuffer.wrap(aBytes, start, 8).order(ByteOrder.BIG_ENDIAN).getLong();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对于这个 Java ByteBuffer 的行为有解释吗? 的相关文章

随机推荐

  • 是否可以找出某个列表是否是固定大小的?

    是否可以找出某些列表是否是固定大小的 我的意思是 例如这段代码 String arr a b List
  • 如何在 Windows 上查询打印队列

    我们正在开发一个关键应用程序 需要对打印的文档进行最好的控制 为了确定打印了哪些文档 我们要检查打印机队列 我们如何查询 Windows 上的打印队列 状态 队列列表 错误 枚举打印机 http msdn microsoft com en
  • Python - 如何从字符串中删除隐藏的符号?

    有时我的字符串里有奇怪的字符 它们在浏览器中不可见 但属于字符串的一部分 并在 len 中计数 我怎样才能摆脱它 Strip 删除正常空间 但不删除该符号 使用来自的字符类别string模块 如果你想允许所有可打印字符 你可以这样做 fro
  • 如何将图像传递给 Django 模板?

    假设views py中对应的函数如下所示 from PIL import Image def get img request img source base image Image open os getcwd deskprod media
  • 为 pyinstaller 创建的 .exe 生成证书

    我为我的公司编写了一个脚本 随机选择员工进行随机药物测试 它工作得非常好 除非我把它交给了使用该程序的人 她点击了它 然后弹出一条消息 询问她是否信任该程序 无论如何点击 运行 后 AVG 在最终加载之前又标记了两次 我读到别人的评论说要在
  • 为什么空行没有存储在变量中

    我正在使用下面的代码 bin bash for host in cat server txt do echo host done server txt 包含 server1 com server2 com server3 com serve
  • 将冻结模型“.pb”文件转换为“.tflite”文件所需的参数 input_arrays 和 output_arrays 是什么?

    我需要转换我的 pb张量流模型和我的 cpkt文件到一个tflite模型以使其在移动设备中工作 有没有什么直接的方法可以找出如何找到我应该用于 input arrays 和 output arrays 的参数 import tensorfl
  • Mongoose getter / setter 用于标准化数据

    I have User模式有一个username场地 我希望此字段区分大小写 以便用户可以注册诸如BobDylan 但是 我需要我的架构来验证新条目 以检查是否有重复项 区分大小写 例如bobdylan 我的研究告诉我 我应该在模式中创建一
  • Delphi 自定义弹出/下拉菜单,如何实现?

    我想制作一个自定义下拉 弹出菜单 其下方有一个很好的阴影 问题是它不是标准菜单 我需要在弹出菜单 下拉菜单中放置一些组件 所以基本上我想要一个下拉菜单 我可以做任何我想做的事情 而不仅仅是简单的菜单项 我希望它像正常的弹出菜单一样工作 问题
  • 箭头键键入大写字母而不是移动光标

    我已经使用 homebrew 安装了最新的 vim 还从 google code 主页安装了 mac vim 在 mac vim 中一切正常 但是当我在 mac 的terminal app 中运行 vim 并进入插入模式时 我会得到 A B
  • 在文件和文件夹的名称中递归地填充 0

    我有一个文件夹 其中包含有关某个特定主题的视频讲座 它的结构如下 1 fol 1 file mp4 2 file mp4 3 file mp4 2 fol 10 file mp4 4 file mp4 5 file mp4 6 file m
  • 谷歌图表重绘/缩放窗口大小

    如何在窗口调整大小时重绘 调整谷歌折线图的大小 为了仅在窗口调整大小完成时重绘并避免多次触发 我认为最好创建一个事件 create trigger to resizeEnd event window resize function if t
  • Kestrel MaxRequestBodySize 上传文件超出限制

    我确实遇到了红隼的一个奇怪的问题 我无法上传超过 kestrel MaxRequestBodySize 的多个文件 预期的行为是抛出BadHttpRequestException当我尝试阅读时this Request Form Files
  • 使用 bash 脚本比较两个文件并打印详细的差异报告

    我在 Unix 系统上有 2 个大文件 每个文件有数千行和大约 80 列 我已根据一组唯一键对文件进行排序 以便我们始终比较相同的行 为了便于理解 我在这里只给出 3 行和 7 列 File 1 d report ref date 2021
  • Angular-Material 设置了只有月份和年份的日期选择器

    我正在使用角度 1 5 9 和角度材料设计 1 1 1 我想添加一个仅包含月份和年份的日期选择器 没有日期 它用于结帐表单中的信用卡到期字段 您可以设置md mode month 下面的工作演示
  • 在opencv上检测非闭合轮廓

    我正在做自动卡检测的计算机视觉项目 我需要将卡片与背景分开 我已经应用了精明的边缘检测 使用自动参数设置 opencv中Canny操作自动计算低阈值和高阈值 https stackoverflow com questions 4292249
  • 将 EJB 作为实例变量注入 servlet 是否安全?

    我们都知道 在 Web 层中 可能只存在给定 Servlet 的单个实例来服务多个请求 这可能会导致实例变量中的线程问题 我的问题是 使用 EJB 注释将 EJB 作为实例变量注入到 servlet 中是否安全 我最初的直觉是否定的 因为假
  • 规范化音频,如何将浮点数组转换为字节数组?

    大家好 我正在播放音频文件 我把它读作byte 然后我需要通过将值放入 1 1 范围内来标准化音频 然后我想将每个浮点值放入byte i 数组然后把它byte 返回到正在播放的音频播放器 我试过这个 byte data ar ReadDat
  • 本地网络上的可靠组播

    我正在使用 C 和 Qt 实现一个消息系统 经过深思熟虑 我确定多播或多播风格的技术最能解决我的问题 然而 我了解到UDP的不可靠性并认为这是不可接受的 我的要求如下 消息将以二进制序列化形式发送 从网络上的任何给定节点 我必须能够向其他节
  • 对于这个 Java ByteBuffer 的行为有解释吗?

    我需要将数值转换为字节数组 例如 要将 long 转换为字节数组 我有以下方法 public static byte longToBytes long l ByteBuffer buff ByteBuffer allocate 8 buff