Как GetBytes () в C # с кодировкой UTF8 с BOM? - PullRequest
43 голосов
/ 11 декабря 2010

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

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

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

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

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

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

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

Ответы [ 4 ]

112 голосов
/ 11 декабря 2010

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

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

9 голосов
/ 15 июня 2015

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

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, для которых требуется спецификация.

2 голосов
/ 11 декабря 2010

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

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

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

0 голосов
/ 11 декабря 2010

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

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

...