OdbcDataReader 读取 Sqlite DB 的奇怪结果
此方法返回一些奇怪的结果,并且想知道是否有人可以解释为什么会发生这种情况,以及可能获得我想要的结果的解决方案。
结果:
FileName = 我期望的
FileSize = 我期望的
Buffer = 所有字节 = 0
BytesRead = 0
BlobString = 二进制数据字符串
FieldType = BLOB (我期望的)
ColumnType = System.String
此外,如果文件大于几 KB,读取器会抛出异常,指出 StringBuilder 容量参数必须大于零(可能是因为大小大于 Int32.MaxValue)。
我想我的问题是如何从 OdbcDataReader 正确读取大 BLOB?
public static String SaveBinaryFile(String Key)
{
try
{
Connect();
OdbcCommand Command = new OdbcCommand("SELECT [_filename_],[_filesize_],[_content_] FROM [_sys_content] WHERE [_key_] = '" + Key + "';", Connection);
OdbcDataReader Reader = Command.ExecuteReader(CommandBehavior.SequentialAccess);
if (Reader.HasRows == false)
return null;
String FileName = Reader.GetString(0);
int FileSize = int.Parse(Reader.GetString(1));
byte[] Buffer = new byte[FileSize];
long BytesRead = Reader.GetBytes(2, 0, Buffer, 0, FileSize);
String BlobString = (String)Reader["_content_"];
String FieldType = Reader.GetDataTypeName(2);
Type ColumnType = Reader.GetFieldType(2);
return null;
}
catch (Exception ex)
{
Tools.ErrorHandler.Catch(ex);
return null;
}
}
This method returns some strange results, and was wondering if someone could explain why this is happening, and possibly a solution to get my desired results.
Results:
FileName = what I'd expect
FileSize = what I'd expect
Buffer = all bytes = 0
BytesRead = 0
BlobString = string of binary data
FieldType = BLOB (what I'd expect)
ColumnType = System.String
Furthermore, if the file is greater than a few KB, the reader throws an exception stating the StringBuilder capacity argument must be greater than zero (presummably because the size is greater than Int32.MaxValue).
I guess my question is how does one properly read large BLOBs from an OdbcDataReader?
public static String SaveBinaryFile(String Key)
{
try
{
Connect();
OdbcCommand Command = new OdbcCommand("SELECT [_filename_],[_filesize_],[_content_] FROM [_sys_content] WHERE [_key_] = '" + Key + "';", Connection);
OdbcDataReader Reader = Command.ExecuteReader(CommandBehavior.SequentialAccess);
if (Reader.HasRows == false)
return null;
String FileName = Reader.GetString(0);
int FileSize = int.Parse(Reader.GetString(1));
byte[] Buffer = new byte[FileSize];
long BytesRead = Reader.GetBytes(2, 0, Buffer, 0, FileSize);
String BlobString = (String)Reader["_content_"];
String FieldType = Reader.GetDataTypeName(2);
Type ColumnType = Reader.GetFieldType(2);
return null;
}
catch (Exception ex)
{
Tools.ErrorHandler.Catch(ex);
return null;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我将该字段创建为 BLOB。 但是,看到您建议 GetFieldType 为 System.String 的结果,我不确定。 我正在使用 SQLite Manager FireFox 管理器插件,它将内容报告为 BLOB。
.NET 和 SQLite 管理器似乎是冲突的。 我可以从管理器中正确保存文件,因此我知道它已正确存储 - 它只是将其读入我的应用程序。
filesize 是一个文本字段,这是我刚刚快速添加的内容,以尝试调试整个事情,我计划迟早更改它。
大小问题对我来说真的很令人惊讶,但我无法解释它(这就是我在这里的原因:)我无法确定确切的大小限制是多少,但我知道它会抛出一个错误,文件仅是34KB。 下面附上我生成的异常报告的副本。
发生错误:2009 年 1 月 4 日下午 1:36
帮助链接:
内部异常:
消息:
“容量”必须大于零。
参数名称:capacity
来源:
mscorlib
StackTrace:
在 System.Text.StringBuilder..ctor(字符串值,Int32 startIndex,Int32 长度,Int32 容量)
在 System.Text.StringBuilder..ctor(字符串值,Int32 容量)
在 System.Data.Odbc.OdbcDataReader.internalGetString(Int32 i)
在 System.Data.Odbc.OdbcDataReader.GetValue(Int32 i,TypeMap 类型映射)
在 System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
在 System.Data.Odbc.OdbcDataReader.get_Item(字符串值)
在 AppEx.Data.DatabaseHandler.SaveBinaryFile(String Key) 中 ...\Data\DatabaseHandler.cs:第 249 行
TargetSite:
无效 .ctor(System.String, Int32, Int32, Int32)
I created the field as a BLOB. However, seeing the results of your suggestion of GetFieldType being a System.String, I'm not sure. I'm using the SQLite Manager FireFox addon to manager, and it's reporting content as a BLOB.
.NET and the SQLite manager seem to be conflicting. I can save the file properly out of the manager so I know it's stored properly -- it's just reading it into my app.
filesize is a text field, it was something I just quickly added to try to debug this whole thing and I plan to change it sooner or later.
The size issue is really surprising to me, but I cannot explain it (which is why I'm here :) I can't determine what the exact size limit is, but I know it will throw an error with a file that is only 34KB. Attached below is a copy of the exception report I generate.
Error Occured: 1:36 PM 1/4/2009
HelpLink:
InnerException:
Message:
'capacity' must be greater than zero.
Parameter name: capacity
Source:
mscorlib
StackTrace:
at System.Text.StringBuilder..ctor(String value, Int32 startIndex, Int32 length, Int32 capacity)
at System.Text.StringBuilder..ctor(String value, Int32 capacity)
at System.Data.Odbc.OdbcDataReader.internalGetString(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i, TypeMap typemap)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
at System.Data.Odbc.OdbcDataReader.get_Item(String value)
at AppEx.Data.DatabaseHandler.SaveBinaryFile(String Key) in ...\Data\DatabaseHandler.cs:line 249
TargetSite:
Void .ctor(System.String, Int32, Int32, Int32)
数据库中的字段类型肯定是BLOB而不是CLOB吗? 它确实看起来好像将其视为文本数据而不是二进制数据。
Reader.GetFieldType(2)
返回什么?作为一个附带问题,filesize 字段真的是字符串而不是整数吗? 你不能只使用
Reader.GetInt32(1)
吗?最后,关于你的大小问题 - 当你谈论“超过几KB”的东西时 - “超过几K”和“大到足以溢出
int.MaxValue
”之间存在很大差异(即 2GB)。 你有几兆字节大小的东西吗?Is the field type in the database definitely a BLOB rather than a CLOB? It certainly looks as if it's treating it as text data instead of binary data. What does
Reader.GetFieldType(2)
return?Just as a side-issue, is the filesize field really a string rather than an integer? Can you not just use
Reader.GetInt32(1)
?Finally, with your size issue - when you talk about something being "more than a few KB" - there's a big difference between "more than a few K" and "big enough to overflow
int.MaxValue
" (which would be 2GB). Do you have anything of a few megabytes in size?