我正在尝试创建一个小的测试应用程序,它读取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 /内存......
答案 0 :(得分:3)
FileStream类缓冲输入和输出。您可以在每次更新后调用Flush()方法来清除内部缓冲区。
要清楚,它只会缓冲到缓冲区大小(4 KB)。
在这种情况下,我认为你的罪魁祸首是SqlExpress。当我执行你的代码并写入我的本地SqlExpress副本时,sqlsrvr进程的内存使用量大约增加了1 GB。当我写入非本地数据库时,我的内存使用率保持不变。
答案 1 :(得分:2)
它缓冲它,因为当你将它保存到varbinary列时,它将成为sql server中LOB数据缓存的一部分。这是它的工作原理。
或者你的意思是它在其他地方得到缓冲?