web-dev-qa-db-ja.com

BOMでUTF8エンコーディングを使用してC#でGetBytes()を実行する方法は?

C#のasp.net mvc 2アプリケーションでUTF8エンコーディングに問題があります。ユーザーに文字列から簡単なテキストファイルをダウンロードさせようとしています。私は次の行でバイト配列を取得しようとしています:

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

しかし、私はそれを使用してダウンロードのためにそれを返すとき:

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

BOMのないファイルを取得したため、クロアチア語の文字が正しく表示されません。これは、エンコード後にバイト配列にBOMが含まれないためです。それらのバイトを手動で挿入しようとすると、正しく表示されますが、それが最善の方法ではありません。

UTF8Encodingクラスインスタンスを作成し、ブール値(true)をコンストラクターに渡してBOMを含めることも試みましたが、どちらも機能しません。

誰にも解決策がありますか?ありがとう!

43
Nebojsa Veron

このようにしてみてください:

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");
}

理由は、ブール値のパラメーターをとるUTF8Encodingコンストラクターが期待どおりに動作しないためです。

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

結果の配列には、値97の単一バイトが含まれます。UTF8はBOMを必要としないため、BOMはありません。

112
Darin Dimitrov

ファイルまたはストリームに書き込まれるときに、任意のエンコーディングの任意の文字列をバイト配列の表現に変換する単純な拡張機能を作成しました。

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

使用法:

stringValue.ToBytes(Encoding.UTF8)

これは、BOMを必要とするUTF-16などの他のエンコーディングでも機能します。

9

UTF-8は1バイトワードのシーケンスであるため、BOMは必要ありません。 UTF-8 = UTF-8BE = UTF-8LE。

対照的に、UTF-16は、ストリームの残りの部分がUTF-16BEかUTF-16LEかを識別するために、ストリームの先頭にBOMを必要とします。ワードのバイトはBEまたはLEです。

問題はEncoding.UTF8クラスにありません。問題は、ファイルの表示に使用しているプログラムにあります。

2
yfeldblum