BLOB の I/O

SqliteBlob クラスはバージョン 3.0 で追加されました。

データベースとの間でデータをストリーミングすることで、ラージ オブジェクトの読み取りと書き込み中のメモリ使用量を削減できます。 これは、データを解析または変換するときに特に便利です。

最初に、通常どおり行を挿入します。 zeroblob() SQL 関数を使用して、ラージ オブジェクトを保持するデータベース内の領域を割り当てます。 last_insert_rowid()関数は、rowid を取得する便利な方法を提供します。

var insertCommand = connection.CreateCommand();
insertCommand.CommandText =
@"
    INSERT INTO data(value)
    VALUES (zeroblob($length));

    SELECT last_insert_rowid();
";
insertCommand.Parameters.AddWithValue("$length", inputStream.Length);
var rowid = (long)insertCommand.ExecuteScalar();

行を挿入した後、 SqliteBlobを使用して大きなオブジェクトを書き込むストリームを開きます。

using (var writeStream = new SqliteBlob(connection, "data", "value", rowid))
{
    // NB: Although SQLite doesn't support async, other types of streams do
    await inputStream.CopyToAsync(writeStream);
}

データベースからラージ オブジェクトをストリーミングするには、ラージ オブジェクトの列に加えて、次に示すように rowid またはそのエイリアスのいずれかを選択する必要があります。 rowid を選択しないと、オブジェクト全体がメモリに読み込まれます。 GetStream()によって返されるオブジェクトは、正常に完了するとSqliteBlobになります。

var selectCommand = connection.CreateCommand();
selectCommand.CommandText =
@"
    SELECT id, value
    FROM data
    LIMIT 1
";
using (var reader = selectCommand.ExecuteReader())
{
    while (reader.Read())
    {
        using (var readStream = reader.GetStream(1))
        {
            await readStream.CopyToAsync(outputStream);
        }
    }
}