如何用C#从Firebird读取二进制blob到byte []?

时间:2016-04-14 10:06:31

标签: c# sql .net firebird

我对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");
}

但我应该放在这里?据我所知,我需要使用流,但我无法理解如何做到这一点。

2 个答案:

答案 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接口。