无法检测到正确的字符编码

时间:2012-02-15 15:45:23

标签: c# character-encoding firebird interbase firebird2.5

我需要从使用InterBase 4.2.1创建的一些旧的interbase数据库文件中提取数据。我正在使用Firebird(版本2.5.1)和.NetProvider(版本2.7.0)的嵌入式版本。我之前从未使用firebird的interbase(但我对SQL SERVER和SQLite有一些经验),在巡航网络并试验了2天之后,我还没有找到解决方案。

数据库中的表包含英文数据,但也包含希伯来语中的数据。像我一样乐观,我开始使用UTF8创建我的连接字符串:

FbConnectionStringBuilder builder = new FbConnectionStringBuilder();
builder.Database = m_DatabaseName;
builder.ServerType = FbServerType.Embedded;
builder.Charset = FbCharset.Utf8.ToString();

但是这给了我以下例外:

bad parameters on attach or create database
CHARACTER SET Utf8 is not defined

我正确使用了fbintl.dll。 (请参阅我的应用程序目录和下面的子目录中的文件)。我甚至使用ProcessMonitor来检查fbintl.dll是否已加载。

fbembed.dll
firebird.log
firebird.msg
FirebirdSql.Data.FirebirdClient.dll
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
MyApplication.exe
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll
intl\fbintl.conf
intl\fbintl.dll
udf\fbudf.dll
udf\ib_udf.dll

所以我尝试枚举FbCharset并尝试连接每个字符集,超过一半的人抛出相同的异常,当我与其他人联系并查询其中一个希伯来字段时(使用{{ 1}}),我总是得到同样的垃圾。我在连接字符串中指定的字符集似乎并不重要,结果总是相同的,即使我根本没有指定任何字符集。

接下来,我查询了数据库IDataReader.GetString()中定义的字符集,并且我填充了这些字符集,尝试连接它们中的每一个,一些引发了异常,其他人给出了与之前相同的结果。

我不清楚创建数据库的字符集,但我检查了数据库中每个字段的字符集,所有文本字段的字符集都设置为'NONE'。

SELECT RDB$CHARACTER_SET_NAME FROM RDB$CHARACTER_SETS

但是我注意到一些系统表的文本字段有UNICODE_FSS作为字符集。我已经在连接字符串中尝试过该字符集,但我仍然可以获得所请求文本字段的garbadge。

我的最后一次尝试是检索字节(使用SELECT r.RDB$RELATION_NAME, r.RDB$FIELD_NAME, f.RDB$FIELD_NAME, cset.RDB$CHARACTER_SET_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID ORDER BY r.RDB$RELATION_NAME ASC, r.RDB$FIELD_POSITION ASC )并自己编码字符串,但这给了我一个强制转换异常(IDataReader.GetBytes()

有没有人对如何阅读这些数据有任何想法?我不需要永久地转换数据库,因为一旦我提取了数据,它们将不再被使用。

编辑:顺便说一下,有没有免费的轻量级interbase / firebird数据库查看器,我似乎找不到任何好的(与SQLiteSpy相比)?

马克

1 个答案:

答案 0 :(得分:3)

我找到了解决方案。

原始数据库写在带有代码页1255的窗口上。当我读取数据时,现在c#使用默认编码生成一个unicode字符串(不是1255)。所以我只是使用默认编码将字符串解码为字节,然后使用正确的编码将字节转换为字符串。

Encoding encoding = Encoding.GetEncoding(1255);
...
if (!datareader.IsDBNull(i))
{
    string value = dataReader.GetString(i);
    if (value.Length > 0)
    {
        byte[] bytes = Encoding.Default.GetBytes(value);
        value = encoding.GetString(bytes);
    }
    // store value
 }

这个解决方案适合我,但我仍然不明白为什么我不能在我的connectionstring中将“WIN1255”指定为charset而不会获得异常bad parameters on attach or create database - CHARACTER SET WIN1255 is not defined? (我甚至尝试过charset“WINDOWS1255”,但后来我得到了例外Invalid character set specified)。