C# 如何从SQL Server读取大文件?
我尝试从SQL Server读取文件(650 MB):C# 如何从SQL Server读取大文件?,c#,sql-server,out-of-memory,C#,Sql Server,Out Of Memory,我尝试从SQL Server读取文件(650 MB): using (var reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { using (var dbStream = reader.GetStream(0)) { if (!reader.IsDBNull(0)) {
using (var reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
if (reader.Read())
{
using (var dbStream = reader.GetStream(0))
{
if (!reader.IsDBNull(0))
{
stream.Position = 0;
dbStream.CopyTo(stream, 256);
}
dbStream.Close();
}
}
reader.Close();
}
但是我在CopyTo()
上得到了OutOfMemoryException
对于小文件,此代码段工作正常。如何处理大文件?您可以将数据以小块的形式读写到某个临时文件中。您可以在上看到示例
确保将
SqlDataReader
与CommandBehavior.SequentialAccess
一起使用,请注意上面代码段中的这一行
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
可以找到有关CommandBehavior
enum的更多信息
编辑:
让我澄清一下。我同意@MickyD的观点,问题的原因不是你是否使用了
CommandBehavior.SequentialAccess
,而是你一次读取了大文件
我之所以强调这一点,是因为开发人员通常会忽略这一点,他们倾向于分块读取文件,但不设置
CommandBehavior。SequentialAccess
他们会遇到其他问题。虽然它已经贴上了原始问题,但在我的回答中强调了给任何新来的人一个点
@MatthewVar stream=new MemoreStream();有什么不对的地方吗?——克利弗马克斯15小时前
您的问题不是您是否正在使用:
`command.ExecuteReader(CommandBehavior.SequentialAccess)`
…正如我们所看到的,你就是这样;或者您的流复制缓冲区大小太大(实际上很小),而您使用的是MemoryStream
,正如您在上面的注释中所指出的那样。很可能您正在加载650MB文件两次,一次来自SQL,另一次存储在内存流中,从而导致OutOfMemoryException
虽然解决方案是改为写入文件流,但在可接受的答案中没有突出显示问题的原因。除非您知道问题的原因,否则您将无法学会在将来避免此类问题。Hmmm….可能会认为即使在x86中也可以工作您将如何处理内存中的流数据?流的具体类型是什么?如果是
MemoryStream
那么这就是你的问题了…@Albert在这种情况下,我想将流保存在文件中。是的,你可以将其写入文件流,但你不必手动滚动循环-你可以像已经做的那样使用stream.CopyTo()
,但只需将MemoryStream
更改为FileStream
。请注意,由于内存碎片,可能会耗尽大量堆空间。已经在块中复制了(在OP的代码中,它只在256字节的块中复制,这似乎太小了…)我感到困惑@马修沃森说,CopyTo()
正是我所需要的。但是@M_Idress说我要重写代码。谁是对的?@MatthewWatson我尝试使用4096而不是256字节,但得到了相同的errorCommandBehavior。顺序访问是这里的重要因素。SequentialAccess允许DataReader以流的形式加载数据,而不是加载整行。但是OP已经在使用CommandBehavior.SequentialAccess
`command.ExecuteReader(CommandBehavior.SequentialAccess)`