我对C#知之甚少,但我需要编写代码,将二进制blob读取到byte[]
。
我写了这段代码:
byte[] userBlob;
myCommand.CommandText = "SELECT id, userblob FROM USERS";
myCommand.Connection = myFBConnection;
myCommand.Transaction = myTransaction;
FbDataReader reader = myCommand.ExecuteReader();
try
{
while(reader.Read())
{
Console.WriteLine(reader.GetString(0));
userBlob = // what I should to do here??
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Can't read data from DB");
}
但我应该放在这里?据我所知,我需要使用流,但我无法理解如何做到这一点。
答案 0 :(得分:2)
byte[] toBytes = Encoding.ASCII.GetBytes(string);
所以,在你的情况下;
userBlob = Encoding.ASCII.GetBytes(reader.GetString(0));
但是,我不确定您要使用代码实现什么,因为您要撤回所有用户,然后反复创建blob。
答案 1 :(得分:0)
游戏有点迟了;我希望这是正确的。
我假设您使用的是Firebird .NET提供程序,它是C#实现,不能在本机fbclient.dll
之上运行。不幸的是,它没有提供到BLOB的流接口,这将允许在不消耗内存的情况下分块读取潜在的巨大数据。
相反,您使用FbDataReader.GetBytes()
方法读取数据,所有数据都必须容纳在内存中。 GetBytes
接收用户提供的缓冲区,并将BLOB数据填充到所引用的位置,然后返回其实际复制的字节数(可能小于完整大小)。
将null
缓冲区传递给GetBytes
会返回BLOB的完整大小(但没有数据!),因此您可以根据需要重新分配。
在这里,我们假设您对字段#0(没有意思)有一个INT,而对于#1有一个BLOB,那么这个幼稚的实现应该处理它:
// temp buffer for all BLOBs, reallocated as needed
byte [] blobbuffer = new byte[512];
while (reader.Read())
{
int id = reader.GetInt32(0); // read first field
// get bytes required for this BLOB
long n = reader.GetBytes(
i: 1, // field number
dataIndex: 0,
buffer: null, // no buffer = size check only
bufferIndex: 0,
length: 0);
// extend buffer if needed
if (n > blobbuffer.Length)
blobbuffer = new byte[n];
// read again into nominally "big enough" buffer
n = reader.GetBytes(1, 0, blobbuffer, 0, blobbuffer.Length);
// Now: <n> bytes of <blobbuffer> has your data. Go at it.
}
可以对此进行一些优化,但是Firebird .NET提供程序确实需要像本机fbclient.dll提供的流式BLOB接口。