我想出了如何让文本以.net形式正确显示。它实际上与字体无关,而且更多的是为.net转换数据。我已经改变了代码,基本上是这样的:
string Name = reader.GetString(column);
到
string Name = System.Text.Encoding.Default.GetString(reader.GetOracleString(column).GetNonUnicodeBytes());
我仍然要确认这不会导致问题,任何其他语言的客户端使用的是已经工作的罚款,但到目前为止希腊语和英语看起来不错。
现在我需要在添加用于保存的OracleCommand参数时反转该过程。原来的代码是这样的:
cmd.Parameters.Add(new OracleParameter(":name", Name));
它节省垃圾。字符串“Name”的值看起来很好。工作的非托管C++代码只是将一个sql语句放在一个字符数组中(希腊文本总是在一个char数组中处理),并通过调用OCI函数(Oracle的API)来执行它。 .net代码使用ODAC(Oracle数据访问客户端)进行数据库访问。
UPDATE:
我已经解决了我的问题(保存)的第二部分,更多地了解正在发生的事情。
的数据来从甲骨文到.NET看起来像这样在内存中,当我把它变成一个.NET字符串数据类型,而不做任何转换:
00 0A 33 79 07 00 00 00 06 00 00 00 d4 00 e1 00 ec 00 e5 00 df 00 ef 00 00 00 00 00 00 00 00 00 00 00 00 ..3y ........t.α.μ.ε.ί.ο..... .......
此字符串显示不正确在.NET为:
Ôáìåßï
在.NET字符串的存储器内容转换后(转化如上所示代码):
00 0a 33 79 07 00 00 00 06 00 00 00 a4 03 b1 03 bc 03 b5 03 af 03 bf 03 00 00 00 00 00 00 00 00 00 00 00 .3y ........¤。 ±.Ό.μ.-。.... ............
您可以看到,对于每个字符,已从低位字节的高半字节中取出3,并将其置于高位字节。
字符串现在显示正确.NET为:
Ταμείο
如以上示出了信息,似乎.NET不同表示字符比非托管C++和Oracle。我做了一些测试,发现突破点是160(十六进制值a0)。所以当使用0到159(00到9f)的字符值时,没有区别。一旦使用160或更高的值,就会有所不同。
我的解决方案只适用于0到255之间的字符值,因为我在转换中删除了字符的高字节。这应该适用于我们的应用程序,尽管我们从来不支持多字节字符集。
我在做字符串转换回的格式保存到Oracle什么简化版本是:
//"name" represents a .net string data type containing the data to save
char[] textChars = new char[4000]; //4000 is the max varchar2 column size in Oracle
byte[] textBytes;
int index = 0;
textBytes = (System.Text.Encoding.Default.GetBytes((name).ToCharArray()));
foreach (byte textByte in textBytes)
{
textChars[index++] = (char)textByte;
}
string textString = new string(textChars, 0, index);
cmd.Parameters.Add(new OracleParameter(":name", (object)(textString)));
这整个事情是这样的黑客 - 如果任何人有一个更好的办法,请分享它。似乎应该有一些简单的方法来处理整个问题。
我很确定我的项目已经在使用Unicode。这就是为什么如果我从.net窗体获取文本并将其粘贴到zApp窗体中,那很好。这些角色的数据不会丢失。但只是为了测试你的建议,我添加了一个带有按钮的新表单,并没有任何提示切换到Unicode。它以同样的方式显示 - 如果我从我的键盘输入希腊语,它会显示正常,但数据库中的希腊语和zApp格式不显示。 – AAyres 2009-08-04 18:40:01
根据我已阅读的有关WE8ISO8859P1的内容,我在Oracle数据库中使用的字符应始终为单个字节长度。 – AAyres 2009-08-06 16:32:50