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

How to read binary blob from Firebird to byte[] with C#?

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

但是我应该放在这里什么?据我了解,我需要使用流,但我不知道该怎么做。

byte[] toBytes = Encoding.ASCII.GetBytes(string);

所以,在你的情况下;

userBlob = Encoding.ASCII.GetBytes(reader.GetString(0));

但是,我不确定您试图用您的代码实现什么,因为您正在撤回所有用户,然后一遍又一遍地创建 blob。

比赛有点晚了;我希望这是对的。

我假设您使用的是 Firebird .NET 提供程序,它是一个 C# 实现,不基于本机 fbclient.dll。不幸的是,它没有为 BLOB 提供流接口,这将允许在不耗尽内存的情况下读取潜在的大数据块。

相反,您使用 FbDataReader.GetBytes() 方法读取数据,并且所有数据都必须适合内存。 GetBytes 获取用户提供的缓冲区并将 BLOB 数据填充到引用的位置,它 returns 它实际复制的字节数(可能小于完整大小)。

null 缓冲区传递给 GetBytes returns 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 接口。