【问题标题】:Java four bytes to binary 'bitmask'Java 四个字节到二进制“位掩码”
【发布时间】:2011-06-12 14:06:48
【问题描述】:

我正在尝试从二进制文件中取出四个字节并将它们转换为位掩码,该位掩码表示数据为零,元数据表示 1。

我假设我需要通过将它们组合在一起将它们转换为 int,然后通过它进行位移以确定是否设置了位位置。

我不知道如何将所有四个组合在一起以获得我可以单步执行的 32 位掩码。

int mask = (((int)hbyte) & 0xff) << 8 | (((int)lbyte) & 0xff);

这会将两个组合在一起(Laurence Gonsalves 在另一篇文章中发布)但我无法弄清楚将四个组合在一起的语法。

或者这是否是 Enumset 的情况,我承认我并不完全理解。

任何建议将不胜感激。

谢谢。

托尼

**只是为此添加另一个快速说明,(我不确定这是否通常允许,所以如果不是,我提前道歉),通过我新创建的 int 并检查是否存在的最佳方法是什么位是否设置?

目前我正在使用if (((comboOfBytes &gt;&gt; bitmaskBit) &amp; 1) == 0),但我不知道这是否是我需要的最优雅的检查方式。

此外,我仍然不完全确定我是否理解移位实际上是如何允许检查所有 32 位的!

再次感谢

【问题讨论】:

    标签: java binary masking


    【解决方案1】:

    您可以使用 DataInputStream 从文件中读取 4 个字节作为 int。

    或者,如果您读取字节 a、b、c、d:

    int comboOfBytes = ((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff);
    

    (& 0xff) 是防止符号位扩展破坏更高字节所必需的。

    【讨论】:

    • 非常感谢迈克。这就是工作!
    【解决方案2】:

    我总是用下面的

    public static int compose(byte x3, byte x2, byte x1, byte x0) {
        return (x3 << 24)
                + ((x2 & 0xFF) << 16)
                + ((x1 & 0xFF) << 8)
                + ((x0  & 0xFF) << 0);
    }
    

    但是,您可能希望改用 DataStream。

    不,EnumSet 不是要走的路。 EnumSet 只是 Enums 专用的 Set 的有效实现。除了序列化之外,它没有任何 IO 功能。

    【讨论】:

    • 我相信这优于 Mike Samuel 解决方案,因为它允许您从不到 4 个字节生成位掩码。我建议使用最终参数来帮助发现维护错误。
    • OT:我从不使用最终参数,因为它使参数列表非常长且难以阅读。但是,我可以接受所有参数默认为最终的。
    【解决方案3】:

    EnumSet 是一组 Enum 元素。你的意思可能是BitSet

    【讨论】:

      【解决方案4】:

      我不知道你在做什么的更大背景,但如果你控制数据结构,如果你需要 32 个标志,我怀疑只创建一个布尔值会容易得多[32]数组。

      是的,位标志可以节省内存,但除非你有数百万个,否则这可能并不重要。

      我并不是说由一堆位标志组成的 int 然后被用来屏蔽数据流不是一个好主意,但我认为它很少是一个好主意。

      p>

      【讨论】:

      • Jay,你是对的,这不是一个好主意,这让我非常头疼! :) 它是 Microsoft 压缩算法的一部分,它使用 4 字节位掩码来表示流中数据和元数据的位置。我认为我遇到问题的原因是 Java 读取字节的方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      • 2018-11-07
      • 2021-07-31
      相关资源
      最近更新 更多