web-dev-qa-db-fra.com

UTF-8 octet [] en chaîne

Supposons que je viens d'utiliser une variable BufferedInputStream pour lire les octets d'un fichier texte codé UTF-8 dans un tableau d'octets. Je sais que je peux utiliser la routine suivante pour convertir les octets en chaîne, mais existe-t-il un moyen plus efficace/plus intelligent de le faire que de simplement parcourir les octets et les convertir? 

public String openFileToString(byte[] _bytes)
{
    String file_string = "";

    for(int i = 0; i < _bytes.length; i++)
    {
        file_string += (char)_bytes[i];
    }

    return file_string;    
}
227
skeryl

Regardez le constructeur pour String

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

Et si vous vous sentez paresseux, vous pouvez utiliser la bibliothèque Apache Commons IO - pour convertir le InputStream en String directement:

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

La classe Java String a un constructeur intégré pour la conversion de tableau d'octets en chaîne.

byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};

String value = new String(byteArray, "UTF-8");
38
Kashif Khan

Pour convertir des données utf-8, vous ne pouvez pas supposer une correspondance 1-1 entre octets et caractères . Essayez ceci:

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

(Bah. Je vois que je vais ralentir en appuyant sur le bouton Publiez votre réponse.)

Pour lire un fichier entier en tant que chaîne, procédez comme suit:

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
        }
    }
}
8
Ted Hopp

Vous pouvez utiliser le constructeur String(byte[] bytes) pour cela. Voir this link pour plus de détails .EDIT Vous devez également prendre en compte le jeu de caractères par défaut de votre plate-forme selon le document Java:

Construit une nouvelle chaîne en décodant le tableau d'octets spécifié à l'aide de le jeu de caractères par défaut de la plateforme. La longueur de la nouvelle chaîne est un fonction du jeu de caractères, et par conséquent peut ne pas être égal à la longueur de le tableau d'octets. Le comportement de ce constructeur lorsque les octets donnés ne sont pas valides car le jeu de caractères par défaut n'est pas spécifié. Le La classe CharsetDecoder doit être utilisée lorsque davantage de contrôle sur le processus de décodage est nécessaire.

4
GETah

Voici une fonction simplifiée qui va lire en octets et créer une chaîne. Cela suppose que vous savez probablement déjà dans quel encodage se trouve le fichier (et sinon par défaut).

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();
}
2
scottt

Vous pouvez utiliser les méthodes décrites dans cette question (d’autant plus que vous démarrez avec un InputStream): Lire/convertir un InputStream en String

En particulier, si vous ne voulez pas vous fier à des bibliothèques externes, vous pouvez essayer cette réponse , qui lit InputStream via un InputStreamReader dans un tampon char[] et l'ajoute à un StringBuilder.

2
Bruno

String a un constructeur qui prend byte [] et charsetname en tant que paramètres :)

1
soulcheck

Sachant que vous utilisez un tableau d'octets UTF-8, vous voudrez certainement utiliser le constructeur String qui accepte un nom de jeu de caractères . Sinon, vous risquez de vous exposer à des vulnérabilités de sécurité basées sur le codage de charset. Notez qu'il jette UnsupportedEncodingException que vous devrez gérer. Quelque chose comme ça:

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

Pourquoi ne pas obtenir ce que vous cherchez dès le départ et lire une chaîne du fichier au lieu d’un tableau d’octets? Quelque chose comme:

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

puis readLine de dedans jusqu'à ce que c'est fait.

0
digitaljoel

Cela implique également une itération, mais c'est bien mieux que de concaténer des chaînes car elles sont très coûteuses.

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();    
}
0
bragboy