Pessoal, estou começando a fazer um programa que transforma a codificação de arquivos em UTF-8. Como posso saber se um arquivo está em formato UTF-8 pelo código Java?
vlews
Pessoal, estou começando a fazer um programa que transforma a codificação de arquivos em UTF-8. Como posso saber se um arquivo está em formato UTF-8 pelo código Java?
vlews
É mais complicado que parece.
a) Pode ser que ele comece pelos seguintes 3 bytes:
EF BB BF
Se ele começar com esses 3 bytes (BOM = Byte Order Marker), é com certeza um arquivo UTF-8.
b) Pode ser que ele não comece com esses bytes. Portanto, para saber se é UTF-8 mesmo, você pode fazer uma de duas coisas:
Texto original:
Áurea Évora Ícaro Óbolo Única Ânfora Ênfase Ônfalo
Codificação em UTF-8:
0000 EF BB BF C3 81 75 72 65 61 20 C3 89 76 6F 72 61 ∩....urea ..vora
0010 20 C3 8D 63 61 72 6F 20 C3 93 62 6F 6C 6F 20 C3 ..caro ..bolo .
0020 9A 6E 69 63 61 20 C3 82 6E 66 6F 72 61 20 C3 8A .nica ..nfora ..
0030 6E 66 61 73 65 20 C3 94 6E 66 61 6C 6F 0D 0A nfase ..nfalo..
Codificação em ISO-8859-1 ou Windows-1252 (o próprio Windows chama de “ANSI” embora não seja exatamente ANSI):
0000 C1 75 72 65 61 20 C9 76 6F 72 61 20 CD 63 61 72 .urea .vora .car
0010 6F 20 D3 62 6F 6C 6F 20 DA 6E 69 63 61 20 C2 6E o .bolo .nica .n
0020 66 6F 72 61 20 CA 6E 66 61 73 65 20 D4 6E 66 61 fora .nfase .nfa
0030 6C 6F 0D 0A lo..
Uma forma boboca é "forçar a barra", ou seja, tentar efetuar a codificação e ver se o Java lança alguma exceção.
Algo como:
byte[] bytes = ...;
String s = null;
if (bytes.length > 3 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
... é UTF-8
} else {
try {
s = new String (bytes, "UTF-8"); // tentar primeiro para ver se é UTF-8
} catch (Exception ex) {
try {
s = new String (bytes, "ISO-8859-1"); // deu pau com UTF-8, deve ser ISO-8859-1
} catch (Exception ex) {
// tente outras codificações se você sabe que pode ser outra.
}
}
Valew, thingol… é mais difícil do que parece mesmo, vou fazer alguns testes…
Idependente da detecção, alguém sabe como posso fazer a conversão?
Bom fiz um teste pegando um arquivo que tem acentos, tipo “ááéééé”, peguei o conteúdo desse arquivo em uma String:
String conteudo = ...;
Writer writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(path))
);
writer.write(new String(conteudo.getBytes(), "UTF-8"));
writer.flush();
writer.close();
Mas quando vou verificar o que ele escreveu ficaram umonte de ???
Que será?
[quote=andre_guitar7]Bom fiz um teste pegando um arquivo que tem acentos, tipo “ááéééé”, peguei o conteúdo desse arquivo em uma String:
String conteudo = ...;
Writer writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(path))
);
writer.write(new String(conteudo.getBytes(), "UTF-8"));
writer.flush();
writer.close();
Mas quando vou verificar o que ele escreveu ficaram umonte de ???
Que será?[/quote]
Bom, não sei qual a codificação padrão usada pelo seu Java. Então você precisa explicitá-la. Por exemplo:
String conteudo = ...;
Writer writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(path), "UTF-8")
);
writer.write(new String(conteudo.getBytes(), "UTF-8"));
writer.flush();
writer.close();
Mas quando vou verificar o que ele escreveu ficaram umonte de ???
[quote=thingol]Mas quando vou verificar o que ele escreveu ficaram umonte de ???
[/quote]
No lugar dos acentos ficaram pontos de interrogação (???)
Fiz o teste da forma que vc colocou, agora no lugar dos caracteres com acentos ficaram outros caracteres diferentes, ficou bem maluco…
Provavelmente você está usando o Notepad ou outro editor, e está tentando visualizar em ANSI (ISO-8859-1). Aí é que você vai visualizar “Áurea” como
?çurea ou coisa parecida.
Não, está aparecendo i com dois pontos em cima, ponto de interrogação de ponta cabeça e o símbolo de 1/2, nessa sequencia, repetido a cada caractere com acento. Quando vou visualizar este arquivo no IE aparece quadradinhos em qquer tipo de codificação setada manualmente no browser… será que não é a forma que estou lendo o arquivo?
[code] BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(path))
);
String linha;
String conteudo = “”;
while((linha = reader.readLine()) != null){
conteudo += linha + “\n”;
}
reader.close();[/code] O resto vc já sabe…
E se eu fosse ler caractere a caractere da minha String… poderia converter os caracteres com acento para UTF-8?
Acho que você precisa analisr o arquivo original.
thingol, vc tinha razão… o Eclipse estava lendo o arquivo na codificação Cp1252, por isso ficara aqueles caracteres esquisitos quando tinha acentos, era só mudar a forma de ele ler aquele arquivo e pronto… bom, meu problema agora é validar pelo código quando um arquivo é UTF-8 ou não… essa condição:
byte[] bytes = ...;
String s = null;
if (bytes.length > 3 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
... é UTF-8
} else {
try {
s = new String (bytes, "UTF-8"); // tentar primeiro para ver se é UTF-8
} catch (Exception ex) {
try {
s = new String (bytes, "ISO-8859-1"); // deu pau com UTF-8, deve ser ISO-8859-1
} catch (Exception ex) {
// tente outras codificações se você sabe que pode ser outra.
}
}
que vc colocou, não deu certo…
thingol, que vc acha… se eu tenho um arquivo em UTF-8 e converto, em Java, para ISO-8859-1, todos os caracteres com acento ficam Ã. É só transformar de UTF-8 para ISO e usar o contais(“Ô).
conteudo = new String(texto.getBytes("ISO-8859-1"));
if(conteudo.contains("Ã")){
//é UTF-8
}else{
//não é
}
muito escroto?