Кодировка символов java UTF-16

Я пытался понять кодировку символов в Java. Символы в Java хранятся в 16 бит с использованием кодировки UTF-16. Поэтому, когда я конвертирую строку, содержащую 6 символов в байт, я получаю 6 байтов, как показано ниже, я ожидаю, что это будет 12. Есть ли какая-то концепция, которую я не вижу?

package learn.java;

public class CharacterTest {

    public static void main(String[] args) {
        String str = "Hadoop";
        byte bt[] = str.getBytes();
        System.out.println("the length of character array is " + bt.length);
    } 
}

O/p: длина массива символов равна 6

В соответствии с @Darshan При попытке кодирования UTF-16 для получения байтов результат также не ожидается.

package learn.java;

    public class CharacterTest {

        public static void main(String[] args) {

            String str = "Hadoop";
            try{
                byte bt[] = str.getBytes("UTF-16");
                System.out.println("the length of character array is " + bt.length);

            }
            catch(Exception e)
            {

            }
        } 
    }

o/p: the length of character array is 14

Ответ 1

В версии UTF-16 вы получаете 14 байтов из-за введенного маркера для различения Big Endian (по умолчанию) и Little Endian. Если вы укажете UTF-16LE, вы получите 12 байтов (мало-значный, не добавлен маркер байтового порядка).

См. http://www.unicode.org/faq/utf_bom.html#gen7


EDIT -. Используйте эту программу для просмотра фактических байтов, сгенерированных разными кодировками:

public class Test {
    public static void main(String args[]) throws Exception {
        // bytes in the first argument, encoded using second argument
        byte[] bs = args[0].getBytes(args[1]);
        System.err.println(bs.length + " bytes:");

        // print hex values of bytes and (if printable), the char itself
        char[] hex = "0123456789ABCDEF".toCharArray();
        for (int i=0; i<bs.length; i++) {
            int b = (bs[i] < 0) ? bs[i] + 256 : bs[i];
            System.err.print(hex[b>>4] + "" + hex[b&0xf] 
                + ( ! Character.isISOControl((char)b) ? ""+(char)b : ".")
                + ( (i%4 == 3) ? "\n" : " "));
        }
        System.err.println();   
    }
}

Например, при работе под UTF-8 (в других кодировках по умолчанию JVM символы FE и FF будут отображаться разными), вывод:

$ javac Test.java  && java -cp . Test hello UTF-16
12 bytes:
FEþ FFÿ 00. 68h
00. 65e 00. 6Cl
00. 6Cl 00. 6Fo

и

$ javac Test.java  && java -cp . Test hello UTF-16LE
10 bytes:
60h 00. 65e 00.
64l 00. 64l 00.
67o 00. 

Ответ 2

В соответствии с String.getBytes() документацией метода строка кодируется в последовательность байтов с использованием кодировки платформы по умолчанию.

Я предполагаю, что ваш набор символов по умолчанию для платформы будет ISO-8859-1 (или аналогичный однобайтовый-w980 > -сервер). Эти кодировки будут кодировать один символ в один байт.

Если вы хотите указать кодировку, используйте метод String.getBytes(Charset) или String.getBytes(String).

О 16-разрядном хранении: так Java хранит в себе символы, а также строки. Он основан на исходной спецификации Unicode.

Ответ 3

String.getBytes() использует кодировку платформы по умолчанию. Попробуйте это

byte bt[] = str.getBytes("UTF-16");

Ответ 4

Для UTF-16 кодирования используйте str.getBytes("UTF-16");

но он дает длину 14 для байта [], пожалуйста, обратитесь к [link] http://rosettacode.org/wiki/String_length для более подробной информации.

Ответ 5

Я думаю, что это поможет: Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без отговорок!) Джоэл Спольский

И это также поможет: "UTF-16 (16-разрядный формат преобразования Unicode) - это кодировка символов [...] Кодировка кодировка переменной длины, поскольку кодовые точки закодированный одним или двумя 16-разрядными кодовыми единицами". (от Wikipedia)