UTF-8 byte a Cadena

Supongamos que acabo de utilizar un BufferedInputStream para leer los bytes de un archivo de texto codificado en UTF-8 en una matriz de bytes. Sé que puedo usar la siguiente rutina para convertir los bytes a una cadena, pero ¿hay una manera más eficiente / más inteligente de hacerlo que simplemente iterar a través de los bytes y convertir cada uno?

 public String openFileToString(byte[] _bytes) { String file_string = ""; for(int i = 0; i < _bytes.length; i++) { file_string += (char)_bytes[i]; } return file_string; } 

Mira el constructor de String

 String str = new String(bytes, StandardCharsets.UTF_8); 

Y si te sientes perezoso, puedes utilizar la biblioteca Apache Commons IO para convertir el InputStream en una cadena directamente:

 String str = IOUtils.toString(inputStream, StandardCharsets.UTF_8); 

La clase Java String tiene un constructor incorporado para convertir una matriz de bytes en una cadena.

 byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46}; String value = new String(byteArray, "UTF-8"); 

Para convertir datos utf-8, no puede asumir una correspondencia 1-1 entre bytes y caracteres. Prueba esto:

 String file_string = new String(bytes, "UTF-8"); 

(Bah. Veo que soy lento para presionar el botón Publicar su respuesta).

Para leer un archivo completo como una cadena, haz algo como esto:

 public String openFileToString(String fileName) throws IOException { InputStream is = new BufferedInputStream(new FileInputStream(fileName)); try { InputStreamReader rdr = new InputStreamReader(is, "UTF-8"); StringBuilder contents = new StringBuilder(); char[] buff = new char[4096]; int len = rdr.read(buff); while (len >= 0) { contents.append(buff, 0, len); } return buff.toString(); } finally { try { is.close(); } catch (Exception e) { // log error in closing the file } } } 

Puede usar el constructor String(byte[] bytes) para eso. Vea este enlace para más detalles. EDITAR También debe considerar el juego de caracteres predeterminado de su plataforma de acuerdo con el documento de Java:

Construye un nuevo String decodificando el conjunto de bytes especificado utilizando el juego de caracteres predeterminado de la plataforma. La longitud de la nueva Cadena es una función del juego de caracteres, y por lo tanto puede no ser igual a la longitud de la matriz de bytes. El comportamiento de este constructor cuando los bytes dados no son válidos en el juego de caracteres predeterminado no está especificado. La clase CharsetDecoder se debe usar cuando se requiere más control sobre el proceso de deencoding.

Puede usar los métodos que se describen en esta pregunta (especialmente desde que comienza con un InputStream): Leer / convertir un InputStream a una Cadena

En particular, si no quiere confiar en bibliotecas externas, puede probar esta respuesta , que lee el InputStream través de un InputStreamReader en un búfer char[] y lo agrega a un StringBuilder .

Aquí hay una función simplificada que leerá en bytes y creará una cadena. Supone que probablemente ya sabe en qué encoding se encuentra el archivo (y de lo contrario se predetermina).

 static final int BUFF_SIZE = 2048; static final String DEFAULT_ENCODING = "utf-8"; public static String readFileToString(String filePath, String encoding) throws IOException { if (encoding == null || encoding.length() == 0) encoding = DEFAULT_ENCODING; StringBuffer content = new StringBuffer(); FileInputStream fis = new FileInputStream(new File(filePath)); byte[] buffer = new byte[BUFF_SIZE]; int bytesRead = 0; while ((bytesRead = fis.read(buffer)) != -1) content.append(new String(buffer, 0, bytesRead, encoding)); fis.close(); return content.toString(); } 

String tiene un constructor que toma byte [] y charsetname como parámetros 🙂

Sabiendo que está tratando con una matriz de bytes UTF-8, definitivamente querrá usar el constructor de cadenas que acepta un nombre de conjunto de caracteres . De lo contrario, puede quedar abierto a algunas vulnerabilidades de seguridad basadas en la encoding de juego de caracteres. Tenga en cuenta que arroja UnsupportedEncodingException que tendrá que manejar. Algo como esto:

 public String openFileToString(String fileName) { String file_string; try { file_string = new String(_bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { // this should never happen because "UTF-8" is hard-coded. throw new IllegalStateException(e); } return file_string; } 

Esto también implica iterar, pero esto es mucho mejor que concatenar cadenas ya que son muy costosas.

 public String openFileToString(String fileName) { StringBuilder s = new StringBuilder(_bytes.length); for(int i = 0; i < _bytes.length; i++) { s.append((char)_bytes[i]); } return s.toString(); } 

¿Por qué no obtener lo que está buscando desde el principio y leer una cadena del archivo en lugar de una matriz de bytes? Algo como:

 BufferedReader in = new BufferedReader(new InputStreamReader( new FileInputStream( "foo.txt"), Charset.forName( "UTF-8")); 

luego lee la línea desde adentro hasta que esté lista.

Yo uso de esta manera

String strIn = new String(_bytes, 0, numBytes);