vs2008 C# 使用 System.Data.SQLite.dll,一切正常。
但是我数据库是以前用C++代码生成的,里面汉字编码格式是GB2312,现在用C# 使用 System.Data.SQLite.dll读取汉字会变成乱码,上网查了查资料,System.Data.SQLite.dll默认会按Utf8格式读取。
...
SQLiteDataReader dr;
...
dr.Read();
...
dr[2].ToString();//这句ToString将GB2312的按Utf8读了
...
因为解析的时候就错了,所以读出来的再用怎么用System.Text.Encoding都转不过来。
我现在想解决的办法一个是:
用SQLiteDataReader里面的
public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length);
但是我看了System.Data.SQLite源代码,需要数据字段类型是blob,而我原来数据库字符串类型定义的是varchar,原来数据库是不能动的。
另一个办法是修改System.Data.SQLite源码,让他按GB2312读取,但是我接触C#时间不长,能力达不到...
也不知道问题说清楚了没有...
请教诸位高手,怎么解决在C#下利用System.Data.SQLite.dll读取汉字编码格式是GB2312的数据库,数据库字符串类型定义的是varchar不是blob?
但是我数据库是以前用C++代码生成的,里面汉字编码格式是GB2312,现在用C# 使用 System.Data.SQLite.dll读取汉字会变成乱码,上网查了查资料,System.Data.SQLite.dll默认会按Utf8格式读取。
...
SQLiteDataReader dr;
...
dr.Read();
...
dr[2].ToString();//这句ToString将GB2312的按Utf8读了
...
因为解析的时候就错了,所以读出来的再用怎么用System.Text.Encoding都转不过来。
我现在想解决的办法一个是:
用SQLiteDataReader里面的
public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length);
但是我看了System.Data.SQLite源代码,需要数据字段类型是blob,而我原来数据库字符串类型定义的是varchar,原来数据库是不能动的。
另一个办法是修改System.Data.SQLite源码,让他按GB2312读取,但是我接触C#时间不长,能力达不到...
也不知道问题说清楚了没有...
请教诸位高手,怎么解决在C#下利用System.Data.SQLite.dll读取汉字编码格式是GB2312的数据库,数据库字符串类型定义的是varchar不是blob?
最好还是统一使用utf-8,以后就不会再有编码转换的问题了
------------------------------------------------------------
我也是这么想的,但是目的就是要和原来c++的数据库兼容,c#封装的是好,可惜没c++直接操作内存灵活,要是System.Data.SQLite能支持varchar类型按二进制数据流读写就好了,ToString直接导致了读出来编码的错误.
To fulminati 哎,要是开源的问题就解决了
------------------------------------------------------------
System.Data.SQLite是开源的,下载地址http://sqlite.phxsoftware.com
SQLiteDataReader dr;
// ...
dr.Read();
// ...
// dr[2].ToString();
byte[] bs = dr[2];
string s = System.Text.Encoding.GetEncoding("GB2312").GetString(bs);
// 这里 s 就是你要的 GB2312 编码的字符串
另外,建议使用 System.Data.Common.DbDataReader,
而不要使用 System.Data.SQLite.SQLiteDataReader。
// ...
dr.Read();
// ...
// dr[2].ToString();
byte[] bs = (byte[])dr[2];
string s = System.Text.Encoding.GetEncoding("GB2312").GetString(bs);
// 这里 s 就是你要的 GB2312 编码的字符串
20 楼的代码中的 dr[2] 前面忘记加了一个 (byte[])。
// ...
dr.Read();
// ...
// dr[2].ToString();
byte[] bs = (byte[])dr[2];
string s = System.Text.Encoding.GetEncoding("GB2312").GetString(bs);
// 这里 s 就是你要的 GB2312 编码的字符串
20 楼的代码中 dr[2] 前面忘记了 (byte[])
1.
SQLiteDataReader dr;
// ...
dr.Read();
// ...
// dr[2].ToString();
byte[] bs = dr[2];
string s = System.Text.Encoding.GetEncoding("GB2312").GetString(bs);
// 这里 s 就是你要的 GB2312 编码的字符串
----------------------------------------------------------------------------
byte[] bs = dr[2];这句过不去 Cannot implicitly convert type 'object' to 'byte[]'. 2.
另外,建议使用 System.Data.Common.DbDataReader,
而不要使用 System.Data.SQLite.SQLiteDataReader。
--------------------------------------------------------------------
SQLiteDataReader继承了DbDataReader
public sealed class SQLiteDataReader : DbDataReader
大哥byte[] bs = (byte[])dr[2];也不行,程序跑到这就飞了
System.Windows.Markup.XamlParseException was unhandled
Message="Cannot create instance of 'Window1' defined in assembly 'SQLiteBrowse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error in up file 'Window1.xaml' Line 1 Position 9."
Source="PresentationFramework"
LineNumber=1
LinePosition=9
StackTrace:
at System.Windows.Markup.XamlParseException.ThrowException(String message, Exception innerException, Int32 lineNumber, Int32 linePosition, Uri baseUri, XamlObjectIds currentXamlObjectIds, XamlObjectIds contextXamlObjectIds, Type objectType)
at System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext, Int32 lineNumber, Int32 linePosition, String message, Exception innerException)
at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException)
at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
at System.Windows.Markup.BamlRecordReader.GetElementAndFlags(BamlElementStartRecord bamlElementStartRecord, Object& element, ReaderFlags& flags, Type& delayCreatedType, Int16& delayCreatedTypeId)
at System.Windows.Markup.BamlRecordReader.BaseReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
at System.Windows.Markup.BamlRecordReader.ReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
at System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
at System.Windows.Markup.TreeBuilder.Parse()
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
at System.Windows.Application.DoStartup()
at System.Windows.Application.<.ctor>b__0(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at SQLiteBrowse.App.Main() in F:\2008\SQLiteBrowse\SQLiteBrowse\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Reflection.TargetInvocationException
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
InnerException: System.InvalidCastException
Message="Unable to cast object of type 'System.String' to type 'System.Byte[]'."
Source="SQLiteBrowse"
StackTrace:
at SQLiteBrowse.Window1..ctor() in F:\2008\SQLiteBrowse\SQLiteBrowse\Window1.xaml.cs:line 54
InnerException:
关键在于:Message="Unable to cast object of type 'System.String' to type 'System.Byte[]'." 这一行。说明原始数据库中该字段就是以 GB2312 编码的字符串。试试下面这个: // ...
long dataOffset = ...; // 这是要读取的字段在数据库记录中的起始位置
int length = ...; // 这是要读取的字段的字节数
string s = GetString(dr, 2, dataOffset, length)
// ...string GetString(DbDataReader dr, int ordinal, long dataOffset, int length)
{
byte[] buffer = new byte[length];
GetBytes(ordinal, dataOffset, buffer, 0, length)
reutrn System.Text.Encoding.GetEncoding("GB2312").GetString(buffer);
}祝你好运!
// ...
long dataOffset = ...; // 这是要读取的字段在数据库记录中的起始位置
int length = ...; // 这是要读取的字段的字节数
string s = GetString(dr, 2, dataOffset, length)
// ...string GetString(DbDataReader dr, int ordinal, long dataOffset, int length)
{
byte[] buffer = new byte[length];
dr.GetBytes(ordinal, dataOffset, buffer, 0, length)
reutrn System.Text.Encoding.GetEncoding("GB2312").GetString(buffer);
}
上面 31 楼又写漏了,应该是 dr.GetBytes(...);
同理,如果可能的话,应该始终只使用 System.Data.Common 命名空间中的类,而不要使用 System.Data.SQLite 命名空间中的类。
先创建一个抽象基类 DbObject:using System;
using System.Data;
using System.Data.Common;namespace Skyiv.Ben.ProvidentFund.Db
{
public abstract class DbObject
{
public string DbName { get; private set; }
protected string dsn { get { return "Data Source=" + DbName; } }
protected DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SQLite"); protected DbObject(string dbName)
{
DbName = dbName;
} protected DbParameter AddParmeter(DbCommand comm, string name, DbType type)
{
var p = comm.CreateParameter();
p.ParameterName = name;
p.DbType = type;
comm.Parameters.Add(p);
return p;
} }
}
然后,对数据库中的每张表,创建一个从 DbObject 派生的类,如下所示:
using System;
using System.IO;
using System.Data;
using System.Data.Common;
using Skyiv.Ben.Common;namespace Skyiv.Ben.ProvidentFund.Db
{
partial class Passwd : DbObject
{
static readonly int bytes = 160 / 8; // SHA1 has 160 bits public Passwd(string dbName)
: base(dbName)
{
} byte[] GetValue(string accno)
{
using (var conn = factory.CreateConnection())
{
conn.ConnectionString = dsn;
conn.Open();
var comm = conn.CreateCommand();
comm.CommandText = "SELECT Value FROM Passwd WHERE Accno=@Accno";
AddParmeter(comm, "Accno", DbType.String).Value = accno;
var bs = comm.ExecuteScalar() as byte[];
if (bs == null) return null;
if (bs.Length != bytes) throw new Exception("密码的密文长度错");
return bs;
}
} void Insert(string accno, byte[] value)
{
using (var conn = factory.CreateConnection())
{
conn.ConnectionString = dsn;
conn.Open();
var comm = conn.CreateCommand();
comm.CommandText = "INSERT INTO Passwd VALUES (@Accno,@Value)";
AddParmeter(comm, "Accno", DbType.String).Value = accno;
AddParmeter(comm, "Value", DbType.Binary).Value = value;
comm.ExecuteNonQuery();
}
} void Upate(string accno, byte[] value)
{
using (var conn = factory.CreateConnection())
{
conn.ConnectionString = dsn;
conn.Open();
var comm = conn.CreateCommand();
comm.CommandText = "UPDATE Passwd SET Value=@Value WHERE Accno=@Accno";
AddParmeter(comm, "Value", DbType.Binary).Value = value;
AddParmeter(comm, "Accno", DbType.String).Value = accno;
if (comm.ExecuteNonQuery() != 1) throw new ArgumentOutOfRangeException("accno", "无此键值");
}
} public int WriteData(BinaryReader br)
{
var recs = 0;
using (var conn = factory.CreateConnection())
{
conn.ConnectionString = dsn;
conn.Open();
var comm = conn.CreateCommand();
CreateTable(comm);
comm.CommandText = "INSERT INTO Passwd VALUES (@Accno,@Value)";
var pAccno = AddParmeter(comm, "Accno", DbType.String);
var pValue = AddParmeter(comm, "Value", DbType.Binary);
comm.Transaction = conn.BeginTransaction();
try
{
for (; ; recs++)
{
pAccno.Value = br.ReadDecimal();
pValue.Value = br.ReadBytes(bytes);
if (bytes != (pValue.Value as byte[]).Length) throw new InvalidDataException("输入文件长度错");
comm.ExecuteNonQuery();
}
}
catch (EndOfStreamException) { }
comm.Transaction.Commit();
}
return recs;
} void CreateTable(DbCommand comm)
{
comm.CommandText =
"CREATE TABLE Passwd (" +
" Accno TEXT PRIMARY KEY," +
" Value BLOB NOT NULL" +
")";
comm.ExecuteNonQuery();
}
}
}这样,我们的代码就可以独立了数据库了,随时可以从 SQLite 切换到 MySQL 等数据库。
...
dr.GetBytes(ordinal, dataOffset, buffer, 0, length);//这句出错了
...
我想根源应该是:字段类型是varchar的不是blob,blob是sqlite为了存放二进制专门设置的类型。.net在试图GetBytes的时候由于类型问题出错了。
SQLiteDataReader里面的就有
long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length);
就是调用DbDataReader的GetBytes...
把字段改成blob类型就好了,网上就有 “让Sqlite3以GB2312编码存储汉字”的例子你关于数据库的建议很好,但是不是我想要的,重申帖子范围:
怎么解决在C#下利用System.Data.SQLite.dll读取汉字编码格式是GB2312的数据库,数据库字符串类型定义的是varchar不是blob?另外。付出错信息
System.Windows.Markup.XamlParseException was unhandled
Message="Cannot create instance of 'Window1' defined in assembly 'SQLiteBrowse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error in up file 'Window1.xaml' Line 1 Position 9."
Source="PresentationFramework"
LineNumber=1
LinePosition=9
StackTrace:
at System.Windows.Markup.XamlParseException.ThrowException(String message, Exception innerException, Int32 lineNumber, Int32 linePosition, Uri baseUri, XamlObjectIds currentXamlObjectIds, XamlObjectIds contextXamlObjectIds, Type objectType)
at System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext, Int32 lineNumber, Int32 linePosition, String message, Exception innerException)
at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException)
at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
at System.Windows.Markup.BamlRecordReader.GetElementAndFlags(BamlElementStartRecord bamlElementStartRecord, Object& element, ReaderFlags& flags, Type& delayCreatedType, Int16& delayCreatedTypeId)
at System.Windows.Markup.BamlRecordReader.BaseReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
at System.Windows.Markup.BamlRecordReader.ReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
at System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
at System.Windows.Markup.TreeBuilder.Parse()
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
at System.Windows.Application.DoStartup()
at System.Windows.Application.<.ctor>b__0(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at SQLiteBrowse.App.Main() in F:\2008\SQLiteBrowse\SQLiteBrowse\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Reflection.TargetInvocationException
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
InnerException: System.InvalidCastException
Message="Specified cast is not valid."
Source="System.Data.SQLite"
StackTrace:
at System.Data.SQLite.SQLiteDataReader.VerifyType(Int32 i, DbType typ)
at System.Data.SQLite.SQLiteDataReader.GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length)
at SQLiteBrowse.Window1.GetString(DbDataReader dr, Int32 ordinal, Int64 dataOffset, Int32 length) in F:\2008\SQLiteBrowse\SQLiteBrowse\Window1.xaml.cs:line 34
at SQLiteBrowse.Window1..ctor() in F:\2008\SQLiteBrowse\SQLiteBrowse\Window1.xaml.cs:line 70
InnerException:
目前在嵌入式下用的sqlite
SQLiteDataReader dr;
// ...
dr.Read();
// ...
// dr[2].ToString();
byte[] bs = (byte[])dr.GetValue(2);
string s = System.Text.Encoding.GetEncoding("GB2312").GetString(bs);
// 这里 s 就是你要的 GB2312 编码的字符串
不过,如果在写程序时尽量注意遵循 SQL 标准的话,切换数据库时要修改的内容也不多。
因为对大多数数据库来说,SELECT、INSERT、UPDATE 等语句差别都不大,可能 CREATE TABLE 等语句会有些差别。
程序执行到此句byte[] bs = (byte[])dr.GetValue(2);依然会飞,
出错信息不贴了,郁闷中...
我看了一个 System.Data.SQLite 的源程序代码,SQLiteConvert.cs 文件的第 49 到 52 行如下所示:
/// <summary>
/// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8
/// </summary>
private static Encoding _utf8 = new UTF8Encoding();
在读取 SQLite 数据库的非 BLOB 字段(包括 TEXT、INTEGER、REAL 等)时,就会用到这个,如下面同一个 cs 文件中的第 109 到 131 行所示:
/// <summary>
/// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
/// </summary>
/// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
/// <param name="nativestringlen">The number of bytes to decode</param>
/// <returns>A string containing the translated character(s)</returns>
public static string UTF8ToString(IntPtr nativestring, int nativestringlen)
{
if (nativestringlen == 0 || nativestring == IntPtr.Zero) return "";
if (nativestringlen == -1)
{
do
{
nativestringlen++;
} while (Marshal.ReadByte(nativestring, nativestringlen) != 0);
} byte[] byteArray = new byte[nativestringlen];
Marshal.Copy(nativestring, byteArray, 0, nativestringlen); return _utf8.GetString(byteArray, 0, nativestringlen);
}
不知道把上述代码中的 new UTF8Encoding() 改为 System.Text.Encoding.GetEncoding("GB2312") 会怎么样?最好是能够在 SQLiteConnection.ConnectionString 中加入一个参数来指定编码方式。不过这样工作量好象很大的样子。
之前我已经尝试修改这句,编译能通过,但是生成的System.Data.SQLite.dll就168K比官方的少了大几百K,当用自己生成的dll访问数据库时候,会出现异常,检查一下是少了SQLite.Interop.DLL,文件夹SQLite.Interop里面的都没编译...,官方的好像是把SQLite.Interop.DLL合成到System.Data.SQLite.dll里面了,但是他给的source确没有(或者是我自己配置的问题),反正我的vs2008编译不了SQLite.Interop里面的内容,我在想是不是和开始配置环境是C#有关系,SQLite.Interop里面是纯c代码其实,这是由第一个问题引出的vs2008如何编译完整的System.Data.SQLite.dll是个新问题,不行我再开一贴讨论这个
正如microblue所说的那样,修改SQliteConvert.cs line52
//private static Encoding _utf8 = new UTF8Encoding();
private static Encoding _utf8 = System.Text.Encoding.GetEncoding("GB2312");
就可以按GB2312读取了,虽然这么改缺点很明显,但是解决了我当前的问题,谢谢!!!另外,vs2008如何编译完整的System.Data.SQLite.dll的问题在http://topic.csdn.net/u/20090603/09/2236072b-da66-459b-b175-fc4676fe984f.html帖子中已经由Dobzhansky解决,一并感谢。最后,感谢大家关注,分比较少,见谅!!!
用.net存储进去的自己是中文,也不会乱码。
建表用sqlite administraor,不要用这个工具录入数据,这样就不会乱码了。
总结System.Data.SQLite.dll,用.net录入进去,再用.net查询出来在utf-8环境下一定不会乱码
、
以前也遇到过