8

FileStream のチャンクを読み取り、それを SQL Server 2005 Express の VarBinary(max) 列に追加する小さなテスト アプリケーションを作成しようとしています。

すべてが機能します-列は想定どおりにいっぱいになりますが、私のマシンはまだすべてをメモリにバッファリングしているようで、理由がわかりません.

次のコード (C#) を使用しています。

using (IDbConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
{
    connection.Open();

    string id = Guid.NewGuid().ToString();

    using (IDbCommand command = connection.CreateCommand())
    {
        command.CommandText = "INSERT INTO [BLOB] ([Id],[Data]) VALUES (@p1,0x0)";

        SqlParameter param = new SqlParameter("@p1", SqlDbType.VarChar);
        param.Value = id;
        command.Parameters.Add(param);

        command.ExecuteNonQuery();
    }

    if (File.Exists(textBox1.Text))
    {
        using (IDbCommand command = connection.CreateCommand())
        {
            command.CommandText = "UPDATE [BLOB] SET [Data].WRITE(@data, @offset, @len) WHERE [Id]=@id";

            SqlParameter dataParam = new SqlParameter("@data", SqlDbType.VarBinary);
            command.Parameters.Add(dataParam);

            SqlParameter offsetParam = new SqlParameter("@offset", SqlDbType.BigInt);
            command.Parameters.Add(offsetParam);

            SqlParameter lengthParam = new SqlParameter("@len", SqlDbType.BigInt);
            command.Parameters.Add(lengthParam);

            SqlParameter idParam = new SqlParameter("@id", SqlDbType.VarChar);
            command.Parameters.Add(idParam);
            idParam.Value = id;

            using (FileStream fs = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                byte[] buffer = new byte[2090400]; //chunk sizes that are multiples of 8040 bytes.
                int read = 0;
                int offset = 0;

                while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    dataParam.Value = buffer;
                    offsetParam.Value = offset;
                    lengthParam.Value = read;

                    command.ExecuteNonQuery();

                    offset += read;
                }
            }
        }
    }
}

ファイルをメモリにバッファリングする理由を誰か教えてもらえますか? byte[]私が使用しているバッファのサイズはわずか 2 MB です。

チャンクごとに新しいバッファを作成することもできますが、それは CPU/メモリの無駄のようにも思えます...

4

2 に答える 2

3

FileStream クラスは、入力と出力をバッファリングします。各更新後に Flush() メソッドを呼び出して、内部バッファーをクリアできます。

明確にするために、バッファサイズ (4 KB) までしかバッファしません。

この場合、あなたの犯人は SqlExpress だと思います。コードを実行して SqlExpress のローカル コピーに書き込んだところ、sqlsrvr プロセスによるメモリ使用量が約 1 GB 跳ね上がりました。ローカル以外のデータベースに書き込んだとき、メモリ使用量は横ばいでした。

于 2009-12-21T21:13:32.343 に答える
2

varbinary列に保存すると、SQLサーバーのLOBデータキャッシュの一部になるため、バッファリングされます。それがどのように機能するかです。

それとも、別の場所にバッファリングされるということですか?

于 2009-12-21T21:06:15.393 に答える