Estou escrevendo um aplicativo da web no Google app Engine. Ele permite que as pessoas basicamente editem o código html que é armazenado como um .html
arquivo no blobstore.
Estou usando fetchData para retornar um byte[]
de todos os caracteres no arquivo. Estou tentando imprimir em um html para que o usuário edite o código html. Tudo funciona muito bem!
Aqui está meu único problema agora:
A matriz de bytes está tendo alguns problemas ao converter de volta para uma string. Citações inteligentes e alguns personagens estão saindo do ar. (? 's ou símbolos japoneses etc.) Especificamente são vários bytes que estou vendo que têm valores negativos que estão causando o problema.
As aspas inteligentes estão voltando como -108
e -109
na matriz de bytes. Por que isso acontece e como posso decodificar os bytes negativos para mostrar a codificação de caracteres correta?
InputStream
e, em seguida, dentrobyte[]
. Agora, quando estou tentando converter obyte[]
em String (preciso usar o corpo da resposta para ataques), recebo personagens realmente engraçados cheios de aspas inteligentes e pontos de interrogação e sei lá o quê. Acredito que o seu problema seja o mesmo que o meu, pois ambos estamos lidandohtml
embyte[]
. Você pode aconselhar?String str=new String(buffer, "Cp1252");
mas sem ajuda.Respostas:
A matriz de bytes contém caracteres em uma codificação especial (que você deve saber). A maneira de convertê-lo em String é:
String decoded = new String(bytes, "UTF-8"); // example for one encoding type
By the way - os bytes brutos aparecem podem aparecer como decimais negativos apenas porque o tipo de dados java
byte
é assinado, ele cobre o intervalo de -128 a 127.-109 = 0x93: Control Code "Set Transmit State"
O valor (-109) é um caractere de controle não imprimível em UNICODE. Portanto, UTF-8 não é a codificação correta para esse fluxo de caracteres.
0x93
em "Windows-1252" está a "citação inteligente" que você está procurando, portanto, o nome Java dessa codificação é "Cp1252". A próxima linha fornece um código de teste:System.out.println(new String(new byte[]{-109}, "Cp1252"));
fonte
byte
tipo de dados Java é assinado. Os valores 'negativos' são apenas bytes com o conjunto de bytes mais significativo. Ele também explica qual é o conjunto de caracteres mais provável que você deve usar - Windows-1252. Você deve saber qual conjunto de caracteres usar de contexto ou convenção, entretanto, sem ter que adivinhar.Java 7 e superior
Você também pode passar a codificação desejada para o
String
construtor como umaCharset
constante de StandardCharsets . Isso pode ser mais seguro do que passar a codificação como umString
, como sugerido nas outras respostas.Por exemplo, para codificação UTF-8
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
fonte
Você pode tentar isso.
String s = new String(bytearray);
fonte
public class Main { /** * Example method for converting a byte to a String. */ public void convertByteToString() { byte b = 65; //Using the static toString method of the Byte class System.out.println(Byte.toString(b)); //Using simple concatenation with an empty String System.out.println(b + ""); //Creating a byte array and passing it to the String constructor System.out.println(new String(new byte[] {b})); } /** * @param args the command line arguments */ public static void main(String[] args) { new Main().convertByteToString(); } }
Resultado
65 65 A
fonte
public static String readFile(String fn) throws IOException { File f = new File(fn); byte[] buffer = new byte[(int)f.length()]; FileInputStream is = new FileInputStream(fn); is.read(buffer); is.close(); return new String(buffer, "UTF-8"); // use desired encoding }
fonte
read
lançar uma exceção.Eu sugiro
Arrays.toString(byte_array);
Depende do seu propósito. Por exemplo, eu queria salvar uma matriz de bytes exatamente como o formato que você pode ver no momento da depuração, que é algo assim:
[1, 2, 3]
Se você quiser salvar exatamente o mesmo valor sem converter os bytes para o formato de caractere,Arrays.toString (byte_array)
faça isso. Mas se você quiser salvar caracteres em vez de bytes, você deve usarString s = new String(byte_array)
. Nesse caso,s
é igual a equivalente a[1, 2, 3]
em formato de caractere.fonte
A resposta anterior de Andreas_D é boa. Vou apenas acrescentar que, onde quer que você esteja exibindo a saída, haverá uma fonte e uma codificação de caracteres e pode não suportar alguns caracteres.
Para descobrir se o problema é Java ou sua tela, faça o seguinte:
for(int i=0;i<str.length();i++) { char ch = str.charAt(i); System.out.println(i+" : "+ch+" "+Integer.toHexString(ch)+((ch=='\ufffd') ? " Unknown character" : "")); }
Java terá mapeado todos os caracteres que não consegue entender para 0xfffd o caractere oficial de caracteres desconhecidos. Se você vir um '?' na saída, mas não está mapeado para 0xfffd, é sua fonte de exibição ou codificação que é o problema, não Java.
fonte