我对 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");
}
但是我应该放在这里什么?据我所知,我需要使用流,但我不知道该怎么做。
最佳答案
比赛有点晚了;我希望这是对的。
我假设您使用的是 Firebird .NET 提供程序,它是一个 C# 实现,不基于 native fbclient.dll
。不幸的是,它没有为 BLOB 提供流接口(interface),这将允许在不耗尽内存的情况下以 block 的形式读取潜在的巨大数据。
相反,您使用 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 提供程序确实需要像 native fbclient.dll 提供的流式 BLOB 接口(interface)。
关于c# - 如何使用 C# 从 Firebird 读取二进制 blob 到 byte[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36619884/