Я отправляюсь текстовые файлы, сохраненные в формате ISO 88591-1, которые содержат символы с диакритикой от латинского 1 диапазона (а также нормальный ASCII a-z, и т.д.). Как я преобразовываю эти файлы в UTF-8, использующий C# так, чтобы однобайтовые символы с диакритикой в ISO 8859-1 стали допустимыми символами UTF-8?
Я попытался использовать StreamReader с ASCIIEncoding и затем преобразование строки ASCII к UTF-8 путем инстанцирования кодирования ascii
и кодирование utf8
и затем использование Encoding.Convert(ascii, utf8, ascii.GetBytes( asciiString) )
— но символы с диакритикой представляются как вопросительные знаки.
Какой шаг я пропускаю?
Вам необходимо получить правильный объект Encoding
. ASCII имеет такое же название: ASCII, что означает, что он поддерживает только 7-битные символы ASCII. Если вы хотите преобразовать файлы, это, вероятно, проще, чем иметь дело с байтовыми массивами напрямую.
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName,
Encoding.GetEncoding("iso-8859-1")))
{
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(
outFileName, Encoding.UTF8))
{
writer.Write(reader.ReadToEnd());
}
}
Однако, если вы хотите сами иметь массивы байтов, это достаточно просто сделать с помощью Encoding.Convert
.
byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"),
Encoding.UTF8, data);
Здесь, однако, важно отметить, что если вы хотите пойти по этому пути, вам следует , а не использовать для ввода-вывода файла программу чтения строк на основе кодирования, такую как StreamReader
. FileStream
подойдет лучше, так как он будет читать фактические байты файлов.
В интересах полного изучения проблемы может сработать что-то вроде этого:
using (System.IO.FileStream input = new System.IO.FileStream(fileName,
System.IO.FileMode.Open,
System.IO.FileAccess.Read))
{
byte[] buffer = new byte[input.Length];
int readLength = 0;
while (readLength < buffer.Length)
readLength += input.Read(buffer, readLength, buffer.Length - readLength);
byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"),
Encoding.UTF8, buffer);
using (System.IO.FileStream output = new System.IO.FileStream(outFileName,
System.IO.FileMode.Create,
System.IO.FileAccess.Write))
{
output.Write(converted, 0, converted.Length);
}
}
В этом примере переменная buffer
заполняется фактическими данными в файле в виде байта
[ ]
, поэтому преобразование не производится. Encoding.Convert
задает кодировку источника и назначения, а затем сохраняет преобразованные байты в переменной с именем ... convert
. Затем это напрямую записывается в выходной файл.
Как я уже сказал, первый вариант с использованием StreamReader
и StreamWriter
будет намного проще, если это все, что вы делаете, но последний пример должен дать вам больше подсказок. относительно того, что на самом деле происходит.
Если файлы относительно небольшие (скажем, ~10 мегабайт), вам понадобится всего две строки кода:
string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1"));
System.IO.File.WriteAllText(outPath, txt);