不编码转换String to/from字节数组

Convert String to/from byte array without encoding

我有一个通过网络连接读取的字节数组,我需要将其转换为不带任何编码的字符串,也就是说,只需将每个字节视为字符的低端并将高端留为零。我还需要做相反的事情,我知道角色的高端总是零。

网上搜索了几个类似的问题,都得到了回复,说明必须更改原始数据源。这不是一个选项,所以请不要建议它。

这在 C 中是微不足道的,但 Java 似乎需要我编写自己的转换例程,这可能非常低效。有没有我错过的简单方法?

这是一个示例代码,它将 String 转换为 byte array 并返回 String,无需编码。

public class Test
{

    public static void main(String[] args)
    {
        Test t = new Test();
        t.Test();
    }

    public void Test()
    {
        String input = "Hèllo world";
        byte[] inputBytes = GetBytes(input);
        String output = GetString(inputBytes);
        System.out.println(output);
    }

    public byte[] GetBytes(String str)
    {
        char[] chars = str.toCharArray();
        byte[] bytes = new byte[chars.length * 2];
        for (int i = 0; i < chars.length; i++)
        {
            bytes[i * 2] = (byte) (chars[i] >> 8);
            bytes[i * 2 + 1] = (byte) chars[i];
        }

        return bytes;
    }

    public String GetString(byte[] bytes)
    {
        char[] chars = new char[bytes.length / 2];
        char[] chars2 = new char[bytes.length / 2];
        for (int i = 0; i < chars2.length; i++)
            chars2[i] = (char) ((bytes[i * 2] << 8) + (bytes[i * 2 + 1] & 0xFF));

        return new String(chars2);

    }
}

这会将字节数组转换为字符串,同时只填充高 8 位。

public static String stringFromBytes(byte byteData[]) {
    char charData[] = new char[byteData.length];
    for(int i = 0; i < charData.length; i++) {
        charData[i] = (char) (((int) byteData[i]) & 0xFF);
    }
    return new String(charData);
}

效率应该还不错。正如 Ben Thurley 所说,如果性能确实是一个问题,请不要首先转换为字符串,而是使用字节数组。

字符串已编码为 Unicode/UTF-16。 UTF-16 意味着最多可以使用 2 个字符串 "characters"(char) 来制作一个可显示的字符。您真正想要使用的是:

byte[] bytes = System.Text.Encoding.Unicode.GetBytes(myString); 

将字符串转换为字节数组。这与您在上面所做的完全相同,只是性能快了 10 倍。如果您想将传输数据减少近一半,我建议将其转换为 UTF8(ASCII 是 UTF8 的子集)——互联网 90% 的时间都使用这种格式,方法是调用:

byte[] bytes = Encoding.UTF8.GetBytes(myString);

要转换回字符串,请使用:

String myString = Encoding.Unicode.GetString(bytes); 

String myString = Encoding.UTF8.GetString(bytes);

使用已弃用的构造函数String(byte[] ascii, int hibyte)

String string = new String(byteArray, 0);

不,你没有遗漏任何东西。没有简单的方法可以做到这一点,因为 Stringchar 用于文本。您显然不想将数据作为文本处理——如果它不是文本,这将完全有意义。你可以按照你建议的困难方式来做。

另一种方法是假设字符编码允许任意字节值 (0-255) 的任意序列。 ISO-8859-1 或 IBM437 均符合条件。 (Windows-1252 只有 251 个代码点。UTF-8 不允许任意序列。)如果您使用 ISO-8859-1,生成的字符串将与您的硬方式相同。

至于效率,处理字节数组的最有效方法是将其保留为字节数组。