如何在带有BOM的UTF8编码的C#中使用GetBytes()?

时间:2010-12-10 23:05:13

标签: asp.net-mvc encoding utf-8 byte-order-mark

我在C#中的asp.net mvc 2应用程序中遇到UTF8编码问题。我正在尝试让用户从字符串下载一个简单的文本文件。我正在尝试使用以下行获取字节数组:

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

但是当我使用以下命令将其返回下载时

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

我得到一个没有BOM的文件,所以我没有正确显示克罗地亚字符。这是因为我的bytes数组在编码后不包含BOM。我手动插入这些字节,然后正确显示,但这不是最好的方法。

我还尝试创建UTF8Encoding类实例并将布尔值(true)传递给其构造函数以包含BOM,但它也不起作用。

任何人都有解决方案吗?谢谢!

4 个答案:

答案 0 :(得分:110)

试试这样:

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的单字节。没有BOM,因为UTF8不需要BOM。

答案 1 :(得分:9)

我创建了一个简单的扩展,可以将任何编码中的任何字符串转换为字节数组在写入文件或流时的表示形式:

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等其他编码。

答案 2 :(得分:2)

UTF-8不需要BOM,因为它是一个1字节字的序列。 UTF-8 = UTF-8BE = UTF-8LE。

相比之下,UTF-16需要在流的开头用BOM来识别流的其余部分是UTF-16BE还是UTF-16LE,因为UTF-16是一个2字节字序列和BOM识别单词中的字节是BE还是LE。

问题不在于Encoding.UTF8类。问题在于您用于查看文件的程序。

答案 3 :(得分:-2)

请记住,.NET字符串在内存中都是unicode,因此如果您可以使用调试器正确地看到csvString,则问题是写入文件。

在我看来,你应该使用与文件相同的编码返回FileResult。尝试设置返回的文件编码,