2016-10-17 4 views
-1

Я прочитал от TCP/IP сокет s:Java байт для преобразования Char

byte[] bbuf = new byte[30]; 
s.getInputStream().read(bbuf); 
for (int i = 0; i < bbuf.length; i++) 
{ 
    System.out.println(Integer.toHexString((int) (bbuf[i] & 0xff))); 
} 

Это выводит CA 68 9F 75, который является то, что я бы ожидать. Теперь я хочу, чтобы использовать символы вместо

char[] cbuf = new char[30]; 
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); 
for (int i = 0; i < cbuf.length; i++) 
{ 
    System.out.println(Integer.toHexString((int) (cbuf[i]))); 
} 

Теперь выхода является CA 68 178 75. Таким образом, третьи байты (и только третьи байты) делают разницу. Я предполагаю, что это связано с наборами символов и что я должен указать набор символов в InputStreamer. Я не знаю, как узнать, какой набор символов я должен использовать. Во-вторых, я удивлен, если из-за наборов символов я получаю беспорядок только с одним символом. Я пробовал все другие персонажи, но это, похоже, единственное, что я смог найти.

Кто может решить эту тайну?

+0

Вам необходимо знать, как символы были закодированы. Я бы попробовал 'UTF-8' вместо вашей кодировки по умолчанию, чтобы начать с. –

ответ

0

собирается преобразовать байты из входного потока в символы, используя character encoding. Поскольку вы явно не указали, какую кодировку символов следует использовать, она будет использовать кодировку символов по умолчанию вашей системы.

Как преобразуются байты, зависит от того, какая кодировка символов используется.

Если данные являются двоичными данными и не представляют текст, закодированный с некоторым кодированием символов, то использование InputStreamReader является неправильным способом для чтения этих данных.

Смотрите также: Streams and readers/writers

1

Ваша проблема заключается в том, что вы сравниваете груши с яблоками; байты не совпадают с символами. В своем коде, характер Ÿ представлена ​​следующим образом:

  • 9F (байт закодированные с помощью Windows-1252)
  • 178 (символ кодируются с использованием UTF-16, который является кодирование Java всегда использует для символов внутренне)

в качестве доказательства того, что я говорю, проверить это:

String myString = "Caña"; 
byte[] bbuf = myString.getBytes();  // [ 43, 61, C3, B1, 61 ] (UTF-8 on my machine) 
char[] cbuf = myString.toCharArray(); // [ 43, 61, F1, 61 ] (Java uses UTF-16 internally) 

Теперь анализ вашей проблемы:

  • Вы взяли байтовый массив из строки, я думаю, делая это: myString.getBytes() как вы не указали кодировку, то система использует по умолчанию в machine (Windows-1252)

  • Когда вы читаете свои байты в String с помощью InputSteanReader и т. д., на самом деле это не проблема, потому что вы читаете с другой (или той же) машины Windows, проблема в том, что вы получаете массив символов (вместо массива байтов), ожидающих иметь тот же результат (используйте myString.getBytes() вместо myString.toCharArray(), и вы правильно увидите свои байты).

Наконец, некоторые советы:

  • Всегда объявляйте Явно кодировку при преобразовании между строками и байтовые массивы:

    byte[] bbuf = myString.getBytes(Charset.forName("UTF-8")); 
    
    String myString = new String(bbuf, Charset.forName("UTF-8")); 
    
  • Никогда не смешивать символы и байты, они не являются то же самое

Смежные вопросы