Estoy escribiendo una aplicación web en Google App Engine. Permite a las personas editar básicamente código html que se almacena como un .html
archivo en el blobstore.
Estoy usando fetchData para devolver uno byte[]
de todos los caracteres del archivo. Estoy intentando imprimir en un html para que el usuario edite el código html. ¡Todo funciona muy bien!
Este es mi único problema ahora:
La matriz de bytes tiene algunos problemas al volver a convertir a una cadena. Las citas inteligentes y un par de personajes están saliendo con un aspecto extraño. (? o símbolos japoneses, etc.) Específicamente, son varios bytes que veo que tienen valores negativos que están causando el problema.
Las comillas tipográficas vuelven como -108
y -109
en la matriz de bytes. ¿Por qué es esto y cómo puedo decodificar los bytes negativos para mostrar la codificación de caracteres correcta?
InputStream
y luego enbyte[]
. Ahora, cuando trato de convertir elbyte[]
en String (necesito usar el cuerpo de respuesta para los ataques), obtengo personajes realmente divertidos llenos de comillas inteligentes y signos de interrogación y demás. Creo que la suya problema es igual que la mía, ya que ambos se trata dehtml
enbyte[]
. ¿Puedes darme un consejo?String str=new String(buffer, "Cp1252");
pero no ayuda.Respuestas:
La matriz de bytes contiene caracteres en una codificación especial (que debe saber). La forma de convertirlo en una cadena es:
String decoded = new String(bytes, "UTF-8"); // example for one encoding type
Por cierto: los bytes sin procesar que aparecen pueden aparecer como decimales negativos solo porque el tipo de datos java
byte
está firmado, cubre el rango de -128 a 127.-109 = 0x93: Control Code "Set Transmit State"
El valor (-109) es un carácter de control no imprimible en UNICODE. Entonces, UTF-8 no es la codificación correcta para ese flujo de caracteres.
0x93
en "Windows-1252" es la "cita inteligente" que está buscando, por lo que el nombre Java de esa codificación es "Cp1252". La siguiente línea proporciona un código de prueba:System.out.println(new String(new byte[]{-109}, "Cp1252"));
fuente
byte
tipo de datos de Java está firmado. Los valores 'negativos' son solo bytes con el conjunto de bytes más significativo. También explica cuál es el conjunto de caracteres más probable que debería usar: Windows-1252. Sin embargo, debe saber qué juego de caracteres usar según el contexto o la convención, sin tener que adivinar.Java 7 y superior
También puede pasar la codificación deseada al
String
constructor como unaCharset
constante de StandardCharsets . Esto puede ser más seguro que pasar la codificación como aString
, como se sugiere en las otras respuestas.Por ejemplo, para codificación UTF-8
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
fuente
Puedes probar esto.
String s = new String(bytearray);
fuente
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(); } }
Salida
65 65 A
fuente
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 }
fuente
read
arroja una excepción.yo sugiero
Arrays.toString(byte_array);
Depende de tu propósito. Por ejemplo, quería guardar una matriz de bytes exactamente como el formato que puede ver en el momento de la depuración que es algo como esto:
[1, 2, 3]
Si desea guardar exactamente el mismo valor sin convertir los bytes a formato de caracteres,Arrays.toString (byte_array)
haga esto. Pero si desea guardar caracteres en lugar de bytes, debe usarString s = new String(byte_array)
. En este caso,s
es equivalente a[1, 2, 3]
en formato de carácter.fuente
La respuesta anterior de Andreas_D es buena. Solo voy a agregar que donde sea que muestre la salida, habrá una fuente y una codificación de caracteres y es posible que no admita algunos caracteres.
Para averiguar si es Java o su pantalla el problema, haga esto:
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 habrá asignado cualquier carácter que no pueda entender a 0xfffd, el carácter oficial para caracteres desconocidos. Si ve un '?' en la salida, pero no está asignado a 0xfffd, es su fuente de visualización o codificación el problema, no Java.
fuente