如何在Java中初始化字节数组?

dfi*_*ing 129 java arrays byte

我必须在java中以字节数组的形式存储一些常量值(UUID),我想知道初始化这些静态数组的最佳方法是什么.这就是我目前正在做的事情,但我觉得必须有一个更好的方法.

private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0,
    0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b,
    0x30, 0x30, (byte)0x9d };
private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d,
    0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00,
    0x36, 0x1b, 0x11, 0x03 };
private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c,
    (byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08,
    0x00, 0x2b, 0x30, 0x30, (byte)0x9d };
...
and so on
Run Code Online (Sandbox Code Playgroud)

有什么我可以使用的效率可能较低,但看起来会更清洁吗?例如:

private static final byte[] CDRIVES =
    new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };
Run Code Online (Sandbox Code Playgroud)

Den*_*ret 106

使用将六角形字符串转换为的函数byte[],您可以这样做

byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");
Run Code Online (Sandbox Code Playgroud)

我建议您使用Dave L定义的函数将十六进制转储的字符串表示转换为使用Java的字节数组?

我将其插入此处以获得最大可读性:

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}
Run Code Online (Sandbox Code Playgroud)

如果你让CDRIVES staticfinal性能下降无关紧要.


小智 70

byte[] myvar = "Any String you want".getBytes();
Run Code Online (Sandbox Code Playgroud)

可以转义字符串文字以提供任何字符:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();
Run Code Online (Sandbox Code Playgroud)

  • 是不是根据海报的要求将字符串"0000"变为"{0x30,0x30,0x30,0x30}"(ASCII)而不是"{0x00,0x00,0x00,0x00}"(二进制)? (47认同)
  • 你没有回答正确的问题. (7认同)
  • 看看问题的标题.然后回头看看这个答案.现在告诉我,它有什么问题?它可能无法解决海报的特定问题,但它确实解决了我的问题.我需要将一个字符串转换为一个字节数组,以用作伪随机数生成器的种子,这就像一个魅力. (5认同)

ste*_*hke 33

在Java 6中,有一种方法可以完全满足您的需求:

private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")
Run Code Online (Sandbox Code Playgroud)

或者你可以使用谷歌番石榴:

import com.google.common.io.BaseEncoding;
private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());
Run Code Online (Sandbox Code Playgroud)

当你使用小数组时,Guava方法是过度的.但是Guava还有可以解析输入流的版本.处理大十六进制输入时,这是一个很好的功能.

  • 遗憾的是,`javax.xml.bind` 在 Java 9 中被删除了。 (4认同)

Jon*_*Jon 7

您可以使用Java UUID类来存储这些值,而不是字节数组:

UUID

public UUID(long mostSigBits,
            long leastSigBits)
Run Code Online (Sandbox Code Playgroud)

使用指定的数据构造新的UUID.mostSigBits用于UUID的最高64位,而且最小位变为UUID的最低64位.


Sam*_*ich 7

在编译时可以通过符号十六进制数字分配的最小内部类型是char,如下所示

private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};
Run Code Online (Sandbox Code Playgroud)

为了拥有等效的字节数组,可以将转换部署为

public static byte[] charToByteArray(char[] x)
{
    final byte[] res = new byte[x.length];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = (byte) x[i];
    }
    return res;
}

public static byte[][] charToByteArray(char[][] x)
{
    final byte[][] res = new byte[x.length][];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = charToByteArray(x[i]);
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)