Как GetBytes() в С# с кодировкой UTF8 с помощью спецификации?
У меня проблема с кодировкой UTF8 в моем приложении asp.net mvc 2 на С#. Я пытаюсь позволить пользователю загрузить простой текстовый файл из строки. Я пытаюсь получить массив байтов со следующей строкой:
var x = Encoding.UTF8.GetBytes(csvString);
но когда я возвращаю его для загрузки, используя:
return File(x, ..., ...);
Я получаю файл без спецификации, поэтому я не получаю хорватских символов правильно. Это связано с тем, что мой байтовый массив не включает спецификацию после кодирования. Я triend вставляю эти байты вручную, а затем он отображается правильно, но это не лучший способ сделать это.
Я также попытался создать экземпляр класса UTF8Encoding и передать логическое значение (true) в его конструктор, чтобы включить спецификацию, но он также не работает.
У кого-нибудь есть решение? Спасибо!
Ответы
Ответ 1
Попробуйте вот так:
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 не требует спецификации.
Ответ 2
Я создал простое расширение для преобразования любой строки в любой кодировке в ее представление байтового массива при записи в файл или поток:
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, для которых требуется спецификация.
Ответ 3
UTF-8 не требует спецификации, поскольку это последовательность 1-байтовых слов. UTF-8 = UTF-8BE = UTF-8LE.
В отличие от этого, UTF-16 требует спецификации в начале потока, чтобы определить, является ли остальная часть потока UTF-16BE или UTF-16LE, поскольку UTF-16 представляет собой последовательность из 2-байтовых слов и спецификацию определяет, являются ли байты в словах BE или LE.
Проблема не связана с классом Encoding.UTF8
. Проблема заключается в том, какую программу вы используете для просмотра файлов.
Ответ 4
Помните, что строки .NET - все юникод, пока они остаются в памяти, поэтому, если вы правильно видите ваш csvString с отладчиком, проблема заключается в записи файла.
По-моему, вы должны вернуть FileResult
с тем же кодированием, что и файлы. Попробуйте установить возвращаемое кодирование файлов,