Мне нужна ваша помощь по поводу того, что меня беспокоит при работе с кодировкой UNICODE в .NET Framework...
Мне приходится взаимодействовать с некоторыми системами данных клиентов с приложениями, отличными от UNICODE, и у этих клиентов есть компании по всему миру (китайские, корейские, российские, ...). Поэтому они должны предоставить мне 8-битный файл ASCII, который будет закодирован их кодовой страницей Windows.
Таким образом, если клиент из Греции пришлет мне текстовый файл, содержащий 'Σ' (сигма-буква 'Σ') в названии продукта, я получу эквивалентную букву, соответствующую кодовой точке 211 ANSI, представленной на моей собственной кодовой странице. На моем компьютере установлена французская Windows, что означает, что кодовая страница Windows-1252, поэтому в этом текстовом файле я буду использовать вместо 'Ó'... Хорошо.
Я знаю, что этот клиент грек, поэтому я могу прочитать его файл, задав кодовую страницу windows-1253 в параметрах импорта.
/// <summary>
/// Convert a string ASCII value using code page encoding to Unicode encoding
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUnicode(string value, int codePage)
{
Encoding windows = Encoding.Default;
Encoding unicode = Encoding.Unicode;
Encoding sp = Encoding.GetEncoding(codePage);
if (sp != null && !String.IsNullOrEmpty(value))
{
// First get bytes in windows encoding
byte[] wbytes = windows.GetBytes(value);
// Check if CodePage to use is different from current Windows one
if (windows.CodePage != sp.CodePage)
{
// Convert to Unicode using SP code page
byte[] ubytes = Encoding.Convert(sp, unicode, wbytes);
return unicode.GetString(ubytes);
}
else
{
// Directly convert to Unicode using windows code page
byte[] ubytes = Encoding.Convert(windows, unicode, wbytes);
return unicode.GetString(ubytes);
}
}
else
{
return value;
}
}
Ну, в конце концов, я получил «Σ» в своем приложении, и я могу сохранить его в своей базе данных SQL Server. Теперь мое приложение должно выполнить некоторые сложные вычисления, а затем я должен вернуть этот файл клиенту с автоматическим экспортом...
Итак, моя проблема в том, что я должен выполнить преобразование UNICODE => ANSI?! Но это не так просто, как я думал вначале...
Я не хочу сохранять кодовую страницу, используемую во время импорта, поэтому моей первой идеей было преобразовать UNICODE в windows-1252, а затем автоматически отправить файл клиентам. Они будут читать экспортированный текстовый файл со своей кодовой страницей, поэтому эта идея меня заинтересовала.
Но проблема в том, что преобразование таким образом ведет себя странно... Вот два разных примера:
1-й пример (я)
char ya = '\u042F';
string strYa = Char.ConvertFromUtf32(ya);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1251 = System.Text.Encoding.GetEncoding(1251);
string strYa1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strYa)));
string strYa1251 = ansi1251.GetString(System.Text.Encoding.Convert(unicode, ansi1251, unicode.GetBytes(strYa)));
Таким образом, strYa1252 содержит '?', тогда как strYa1251 содержит действительный char 'я'. Таким образом, кажется, что невозможно преобразовать в ANSI, если действительная кодовая страница не указана для функции Convert () ... Итак, ничто в классе кодирования Unicode не помогает пользователю получить эквивалентность между кодовыми точками ANSI и UNICODE? :\
2-й пример (Σ)
char sigma = '\u3A3';
string strSigma = Char.ConvertFromUtf32(sigma);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1253 = System.Text.Encoding.GetEncoding(1253);
string strSigma1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strSigma)));
string strSigma1253 = ansi1253.GetString(System.Text.Encoding.Convert(unicode, ansi1253, unicode.GetBytes(strSigma)));
В настоящее время у меня есть правильный «Σ» в строке strSigma1253, но у меня также есть «S» для strSigma1252< /сильный>. Как указано в начале, у меня должен быть 'Ó', если был найден код ANSI, или '?' если символ не найден, но не 'S'. Почему? Да, конечно, лингвист мог бы сказать, что буква «S» эквивалентна греческой букве сигма, потому что они звучат одинаково в обоих алфавитах, но у них разные коды ANSI!
Итак, как функция Convert() в среде .NET может справиться с такой эквивалентностью?
И есть ли у кого-нибудь идея записывать символы ANSI из UNICODE в текстовые файлы, которые я должен отправлять клиентам?