web-dev-qa-db-fra.com

Comment GetBytes () en C # avec le codage UTF8 avec BOM?

J'ai un problème avec l'encodage UTF8 dans mon application asp.net mvc 2 en C #. J'essaie de laisser l'utilisateur télécharger un simple fichier texte à partir d'une chaîne. J'essaie d'obtenir un tableau d'octets avec la ligne suivante:

var x = Encoding.UTF8.GetBytes(csvString);

mais quand je le renvoie pour téléchargement en utilisant:

return File(x, ..., ...);

Je reçois un fichier sans nomenclature, donc les caractères croates ne s'affichent pas correctement. En effet, mon tableau d'octets n'inclut pas la nomenclature après l'encodage. Je triend en insérant ces octets manuellement, puis cela s'affiche correctement, mais ce n'est pas la meilleure façon de le faire.

J'ai également essayé de créer une instance de classe UTF8Encoding et de passer une valeur booléenne (true) à son constructeur pour inclure la nomenclature, mais cela ne fonctionne pas non plus.

Quelqu'un a une solution? Merci!

43
Nebojsa Veron

Essayez comme ceci:

public ActionResult Download()
{
    var data = Encoding.UTF8.GetBytes("some data");
    var result = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
    return File(result, "application/csv", "foo.csv");
}

La raison en est que le constructeur UTF8Encoding qui prend un paramètre booléen ne fait pas ce que vous attendez:

byte[] bytes = new UTF8Encoding(true).GetBytes("a");

Le tableau résultant contiendrait un seul octet avec la valeur de 97. Il n'y a pas de nomenclature car UTF8 ne nécessite pas de nomenclature.

112
Darin Dimitrov

J'ai créé une extension simple pour convertir n'importe quelle chaîne dans n'importe quel encodage en sa représentation du tableau d'octets lorsqu'elle est écrite dans un fichier ou un flux:

public static class StreamExtensions
{
    public static byte[] ToBytes(this string value, Encoding encoding)
    {
        using (var stream = new MemoryStream())
        using (var sw = new StreamWriter(stream, encoding))
        {
            sw.Write(value);
            sw.Flush();
            return stream.ToArray();
        }
    }
}

Usage:

stringValue.ToBytes(Encoding.UTF8)

Cela fonctionnera également pour d'autres encodages comme UTF-16 qui nécessite la nomenclature.

9
Hovhannes Hakobyan

UTF-8 ne nécessite pas de nomenclature, car il s'agit d'une séquence de mots de 1 octet. UTF-8 = UTF-8BE = UTF-8LE.

En revanche, UTF-16 nécessite une nomenclature au début du flux pour identifier si le reste du flux est UTF-16BE ou UTF-16LE, car UTF-16 est une séquence de mots de 2 octets et la nomenclature identifie si la les octets dans les mots sont BE ou LE.

Le problème ne vient pas du Encoding.UTF8 classe. Le problème réside dans le programme que vous utilisez pour afficher les fichiers.

2
yfeldblum