Преобразование InputStream в строку и туда и обратно с использованием UTF8 в java

Рассмотрим следующий фрагмент кода

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]

Может ли кто-нибудь предложить, как мы можем преобразовать строку в исходный массив байтов


person Yashpal Singla    schedule 15.12.2017    source источник
comment
Ваш массив байтов не является допустимой строкой UTF-8.   -  person tkausl    schedule 15.12.2017
comment
посмотрите, сколько байтов составляет символ utf-8. stackoverflow.com/questions/10229156 /   -  person dskow    schedule 15.12.2017
comment
Если ваш InputStream содержит эти символы, то он не читает из источника UTF-8. Прежде всего убедитесь, что вы используете правильную кодировку.   -  person Klitos Kyriacou    schedule 15.12.2017
comment
Я до сих пор не могу понять, зачем вам нужны подписанные значения для преобразования UTF-8.   -  person LowLevel    schedule 15.12.2017
comment
Здесь нет InputStream.   -  person user207421    schedule 15.12.2017
comment
На самом деле это какой-то проект обслуживания, и код уже был написан таким образом... что является причиной повреждения данных, сейчас я пытаюсь написать слой адаптера выше, чтобы восстановить данные.   -  person Yashpal Singla    schedule 16.12.2017


Ответы (3)


Самый стабильный ответ заключается в том, что вы должны перейти между массивом байтов и шестнадцатеричной строкой, которая находится между 1 byte == 2 character между 0 и F в формате UTF-8.

Затем преобразуйте обратно из шестнадцатеричного в байтовый массив. К другим вопросам трассировки стека, чтобы узнать, как к ним перейти.

Байт в шестнадцатеричный: Как преобразовать массив байтов в шестнадцатеричную строку в Java?

Hex в байт: Преобразовать строковое представление шестнадцатеричного дампа в байтовый массив с помощью Java?

person dskow    schedule 15.12.2017

Хотя я не могу понять, почему вам нужна недопустимая строка UTF-8, у меня есть объясняющее решение для вас (вставьте этот код в свой класс TestDrive (выполняемый класс, содержащий static void main(String[] args) function:

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;
}
person LowLevel    schedule 15.12.2017

Самый стабильный ответ — оставить массив байтов в покое и передавать его по кругу, полностью избегая String и кругового обхода. Строка не является контейнером для двоичных данных.

person user207421    schedule 15.12.2017