2011-05-16 10 views
6

I analizar etiquetas mp3.¿Cómo convertir una cadena de letras cirílicas rusas?

String artist - No sé lo que estaba en la codificación

Ïåñíÿ ïðî íàäåæäó - ejemplo de cadena en ruso "Песня про надежду"

utilizo http://code.google.com/p/juniversalchardet/

código:

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; 
    } 

y encubierta

new String(text.getBytes(encoding), "cp1251"); -pero esto no funciona.

si uso UTF-16

new String(text.getBytes("UTF-16"), "cp1251") retorno "юя П е с н я п р о н а д е ж д у" espacio - no el espacio es CHAR

EDIT:

esta primera lectura bytes

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

cadena s = new String (abyFrameData, "????");

+0

¿Cómo le va el parámetro de cadena de texto ? quizás el problema tiene que ver con la forma en que está creando la entrada al detector. Las cadenas java siempre son UTF-16, por lo que ya ha habido una conversión de caracteres en ese punto. – stevevls

+1

'nueva cadena (text.getBytes ("UTF-16"), "CP1251")' no hace lo que usted cree. Lo que realmente hace es tomar una cadena existente, recuperar sus bytes como UTF-16, y luego intentar crear una nueva cadena pretendiendo que esos bytes de bytes son CP1251. Lo cual está garantizado que es incorrecto. – Anon

+0

@ stevevls, hmmm Strings Java son siempre la codificación UTF-16, no Unicode http://download.oracle.com/javase/tutorial/i18n/text/index.html – mKorbel

Respuesta

4

Las cadenas de Java son UTF-16. Todas las demás codificaciones se pueden representar mediante secuencias de bytes. Para decodificar datos de caracteres, debe proporcionar la codificación cuando crea la cadena por primera vez. Si tiene una cadena dañada, ya es demasiado tarde.

Suponiendo que ID3, las especificaciones definen las reglas para la codificación. Por ejemplo, ID3v2.4.0 podría restringir las codificaciones utilizadas a través de un encabezado extendido:

q - codificación de texto restricciones

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

manipulación de codificación se define más abajo en el documento:

Si nada más se dice, las cadenas, incluyendo cadenas numéricas y URL, están representados como ISO-8859-1 caracteres en el rango $ 20 - $ FF. Tales cadenas se representan en las descripciones de de marcos como <text string>, o <full text string> si las nuevas líneas son permitidas. Si no se dice nada más, , el carácter de nueva línea está prohibido. En ISO-8859-1 se representa una nueva línea, cuando está permitido, con $ 0A solamente.

Marcos que permiten diferentes tipos de codificación de texto contiene una codificación de texto descripción byte. Codificaciones posibles:

$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. 

clases de uso de transcodificación como InputStreamReader o (más probablemente en este caso) el String(byte[],Charset) constructor para decodificar los datos.Vea también Java: a rough guide to character encoding.


Análisis de los componentes de cadena de una estructura de datos ID3v2.4.0 haría algo como esto:

//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

Leo esto ... pero no entiendo. Edito mi publicación. – Mediator

0

Esto es que funciona para mí:

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); 
Cuestiones relacionadas