Как преобразовать строку русских букв кириллицы? - PullRequest
6 голосов
/ 16 мая 2011

Я разбираю mp3 теги.

String artist - я не знаю, что было в кодировке

Ïåñíÿ ïðî íàäåæäó - пример строки на русском языке "Песня про надежду"

Я использую http://code.google.com/p/juniversalchardet/

Код:

String GetEncoding(String text) throws IOException {
        byte[] buf = new byte[4096];


        InputStream fis = new ByteArrayInputStream(text.getBytes());


        UniversalDetector detector = new UniversalDetector(null);

        int nread;
        while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
            detector.handleData(buf, 0, nread);
        }
        detector.dataEnd();
        String encoding = detector.getDetectedCharset();
        detector.reset();
        return encoding;
    }

и тайное

new String(text.getBytes(encoding), "cp1251"); - но это не работает.

если я использую utf-16

new String(text.getBytes("UTF-16"), "cp1251") возвращать пробел "не является символом пробела"

EDIT:

это первые прочитанные байты

byte[] abyFrameData = new byte[iTagSize];
oID3DIS.readFully(abyFrameData);
ByteArrayInputStream oFrameBAIS = new ByteArrayInputStream(abyFrameData);

String s = новая строка (abyFrameData, "????");

Ответы [ 2 ]

4 голосов
/ 16 мая 2011

Java-строки имеют формат UTF-16.Все остальные кодировки могут быть представлены с использованием байтовых последовательностей.Чтобы декодировать символьные данные, вы должны предоставить кодировку при первом создании строки.Если у вас есть поврежденная строка, это уже слишком поздно.

Предполагая ID3, спецификации определяют правила для кодирования.Например, ID3v2.4.0 может ограничивать кодировки, используемые через расширенный заголовок:

q - Ограничения кодировки текста

   0    No restrictions
   1    Strings are only encoded with ISO-8859-1 [ISO-8859-1] or
        UTF-8 [UTF-8].

Обработка кодировкиопределяется далее в документе:

Если больше ничего не сказано, строки, включая числовые строки и URL-адреса, представляются в виде символов ISO-8859-1 в диапазоне от $ 20 до $ FF.Такие строки представлены в описаниях фреймов как <text string> или <full text string>, если разрешены переводы строки.Если ничего не сказано, символ новой строки запрещен.В ISO-8859-1 новая строка представлена, когда это разрешено, только с $ 0 А.

Кадры, которые допускают различные типы кодирования текста, содержат байт описания кодировки текста.Возможные кодировки:

 $00   ISO-8859-1 [ISO-8859-1]. Terminated with $00.
 $01   UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
       strings in the same frame SHALL have the same byteorder.
       Terminated with $00 00.
 $02   UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
       Terminated with $00 00.
 $03   UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with
       $00.

Используйте классы транскодирования, такие как InputStreamReader или (более вероятно, в этом случае) конструктор String(byte[],Charset) для декодирования данных.См. Также Java: приблизительное руководство по кодированию символов .


При анализе компонентов строки в структуре данных ID3v2.4.0 будет выглядеть примерно так:

//untested code
public String parseID3String(DataInputStream in) throws IOException {
  String[] encodings = { "ISO-8859-1", "UTF-16", "UTF-16BE", "UTF-8" };
  String encoding = encodings[in.read()];
  byte[] terminator =
      encoding.startsWith("UTF-16") ? new byte[2] : new byte[1];
  byte[] buf = terminator.clone();
  ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  do {
    in.readFully(buf);
    buffer.write(buf);
  } while (!Arrays.equals(terminator, buf));
  return new String(buffer.toByteArray(), encoding);
}
0 голосов
/ 07 мая 2014

Это работает для меня:

byte[] bytes = s.getBytes("ISO-8859-1");
UniversalDetector encDetector = new UniversalDetector(null);
encDetector.handleData(bytes, 0, bytes.length);
encDetector.dataEnd();
String encoding = encDetector.getDetectedCharset();
if (encoding != null) s = new String(bytes, encoding);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...