Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从SQL Server读取大文件?_C#_Sql Server_Out Of Memory - Fatal编程技术网

C# 如何从SQL Server读取大文件?

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)) {

我尝试从SQL Server读取文件(650 MB):

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)`