Как GetBytes () в C# с кодировкой UTF8 с помощью BOM?

у меня проблема с кодировкой UTF8 в моем asp.net приложение mvc 2 на C#. Я пытаюсь позволить пользователю загрузить простой текстовый файл из строки. Я пытаюсь получить массив байтов со следующей строкой:

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

но когда я возвращаю его для загрузки, используя:

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

Я получаю файл, который без BOM, поэтому я не получаю хорватские символы правильно. Это связано с тем, что мой массив байтов не включает BOM после кодирования. Я triend вставляет эти байты вручную, а затем он отображается правильно, но это не лучший способ сделать это.

Я также попытался создать экземпляр класса UTF8Encoding и передать логическое значение (true) его конструктору для включения BOM, но он также не работает.

у кого есть решение? Спасибо!

4 ответов


попробуйте так:

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 не требует спецификации.


Я создал простое расширение для преобразования любой строки в любой кодировке в ее представление байтового массива при записи в файл или поток:

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)

это будет работать также для других кодировок, таких как UTF-16, для которых требуется спецификация.


UTF-8 не требует спецификации, потому что это последовательность 1-байтовых слов. UTF-8 = UTF-8BE = UTF-8LE.

напротив, UTF-16 требует спецификации в начале потока, чтобы определить, является ли оставшаяся часть потока UTF-16BE или UTF-16LE, потому что UTF-16 представляет собой последовательность 2-байтовых слов, и спецификация определяет, являются ли байты в словах BE или LE.

проблема не с Encoding.UTF8 класса. Проблема заключается в любой программе, которую вы используете для просмотра файлов.


помните, что строки .NET-это все unicode, пока они остаются в памяти, поэтому, если вы правильно видите csvString с отладчиком, проблема заключается в записи файла.

на мой взгляд вы должны возвратить FileResult с той же кодировкой, что файлы. Попробуйте установить кодировку возвращаемого файла,