【问题标题】:Convert InputStream to String and Round Trip Using UTF8 in java在 java 中使用 UTF8 将 InputStream 转换为字符串和往返
【发布时间】:2018-05-29 23:01:38
【问题描述】:

考虑下面的代码sn-p

byte[] b = new byte[]{ 0, 0, 0, -127 };  // possible Byte Array

// converted byte array to String using UTF-8
String s = String(b, StandardCharsets.UTF_8); 

现在再次尝试将字符串转换为字节数组

b = s.getBytes(StandardCharsets.UTF_8);

现在当我们将它与原始字节数组进行比较时,往返时的值不一样

[0, 0, 0, -17, -65, -67]

谁能建议我们如何将字符串转换回原始字节数组

【问题讨论】:

  • 您的字节数组不是有效的 UTF-8 字符串。
  • 查看一个 utf-8 字符有多少字节。 stackoverflow.com/questions/10229156/…
  • 如果您的 InputStream 包含这些字符,那么它不是从 UTF-8 源读取的。首先确保使用正确的编码。
  • 我仍然无法理解为什么您需要有符号值来进行 UTF-8 转换
  • 这里没有InputStream。

标签: java arrays string utf


【解决方案1】:

最稳定的答案是你应该在一个字节数组和一个十六进制字符串之间切换,即1 byte == 2 character0F 之间,格式为UTF-8

然后从十六进制转换回字节数组到其他堆栈跟踪问题,了解如何找到它们。

字节到十六进制: How to convert a byte array to a hex string in Java?

十六进制转字节: Convert a string representation of a hex dump to a byte array using Java?

【讨论】:

    【解决方案2】:

    虽然我无法理解您需要无效 UTF-8 字符串的原因,但我有一个 解释 解决方案(将此代码粘贴到您的 TestDrive 类(包含 @ 987654322@:

    public static void main(String[] args) {
        byte[] bytes1 = new byte[]{0, 0, 0, -127};
        int[] unsigned = toUnsignedInt(bytes1);
        String utf8String = toUtf8String(unsigned);
        char[] chars = utf8String.toCharArray();
        byte[] bytes2 = toBytes(chars);
        System.out.println(Arrays.equals(bytes1, bytes2));
    }
    
    private static int[] toSigned(byte[] unsigned) {
        int[] signed = new int[unsigned.length];
        for (int i = 0; i < unsigned.length; i++) {
            signed[i] = 2;
        }
        return signed;
    }
    
    private static int[] toUnsignedInt(byte[] signed) {
        int[] unsigned = new int[signed.length];
        for (int i = 0; i < signed.length; i++) {
            unsigned[i] = Byte.toUnsignedInt(signed[i]);
        }
        return unsigned;
    }
    
    private static String toUtf8String(int[] unsigned) {
        char[] chars = toChars(unsigned);
        return new String(chars);
    }
    
    private static char[] toChars(int[] unsigned) {
        char[] chars = new char[unsigned.length];
        for (int i = 0; i < unsigned.length; i++) {
            chars[i] = (char) unsigned[i];
        }
        return chars;
    }
    
    private static byte[] toBytes(char[] chars) {
        int[] unsigned = toUnsignedInt(chars);
        byte[] bytes = new byte[unsigned.length];
        for (int i = 0; i < unsigned.length; i++) {
            bytes[i] = (byte) unsigned[i];
        }
        return bytes;
    }
    
    private static int[] toUnsignedInt(char[] chars) {
        int[] unsigned = new int[chars.length];
        for (int i = 0; i < chars.length; i++) {
            unsigned[i] = (int) chars[i];
        }
        return unsigned;
    }
    

    【讨论】:

      【解决方案3】:

      最稳定的答案是不理会字节数组并传递it,并完全避免字符串和往返。字符串不是二进制数据的容器。

      【讨论】:

        猜你喜欢
        • 2010-12-18
        • 2010-10-21
        • 1970-01-01
        • 2018-11-05
        • 2014-01-29
        • 1970-01-01
        • 2018-11-03
        • 2010-09-23
        相关资源
        最近更新 更多