Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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# 从数据库中传输文件内容_C#_Asp.net_Asp.net Mvc_Filestream - Fatal编程技术网

C# 从数据库中传输文件内容

C# 从数据库中传输文件内容,c#,asp.net,asp.net-mvc,filestream,C#,Asp.net,Asp.net Mvc,Filestream,回到WebForms时代,我可以使用Response.OutputStream.Write()和Response.Flush()将文件数据分块到客户端,因为我们正在传输的文件非常大,会消耗太多web服务器内存。我现在如何使用新的MVC类,如FileStreamResult 我的确切情况是:DB在VarBinary列中包含文件数据(CSV或XLS)。在WebForms实现中,我向DataAccess层发送一个System.Func,该层将遍历IDataReader,并使用System.Func将内

回到WebForms时代,我可以使用
Response.OutputStream.Write()
Response.Flush()
将文件数据分块到客户端,因为我们正在传输的文件非常大,会消耗太多web服务器内存。我现在如何使用新的MVC类,如
FileStreamResult

我的确切情况是:DB在
VarBinary
列中包含文件数据(CSV或XLS)。在WebForms实现中,我向DataAccess层发送一个
System.Func
,该层将遍历
IDataReader
,并使用
System.Func
将内容流式传输到客户端。关键是我不希望webapp必须具备任何特定的数据库知识,包括
IDataReader

如何使用MVC实现相同的结果

Func是(我在web层中定义并发送到DB层):

如果要重用,需要创建从数据库读取数据的
-派生类,并将该流传递到
文件流结果

这种方法存在一些问题

  • 操作结果是同步执行的,所以当从DB/send读取数据时,您的下载不会释放线程-对于少量并行下载可能是可以的。为了解决这个问题,您可能需要直接使用处理程序或从异步操作下载(MVC方法感觉不正确)
  • 至少旧版本的
    FileStreamResult
    没有“流”支持(),请确保您没有问题
Thx。我很快就开始创建自己的从IDataReader读取的流派生类。它似乎并不直截了当,也没有从谷歌搜索中找到任何例子。有什么建议吗?@Ed.S。没有,我没有样品。要创建自定义流,只需从
stream
派生并实现
Read
方法-对于这种情况来说应该足够了(需要几个其他方法,但不需要真正的实现)。很好的一点是,您可以从
Read
返回的字节数少于所请求的字节数-因此每次请求时,只需从
IDataReader
读取一些固定数量的字节。有关读取字节的一些示例,请参阅。对此很好奇……您不希望Web上有任何“DB引用”……但考虑到您正在将响应的引用(在Func中)向下传递到DB……DB层是否需要引用“Web stuff”?或者,因为只向DB传递Func参数,而不传递公共“Web参数”,所以不需要它?
Func<byte[], long, bool> partialUpdateFunc = (data, length) =>
    {
        if (Response.IsClientConnected)
        {
            // Write the data to the current output stream.
            Response.OutputStream.Write(data, 0, (int) length);

            // Flush the data to the HTML output.
            Response.Flush();

            return true;
        }
        else
        {
            return false;
        }
    };
using (var reader = conn.ExecuteReader())
{
    if (reader.Read())
    {
        byte[] outByte = new byte[BufferSize];
        long startIndex = 0;
        // Read bytes into outByte[] and retain the number of bytes returned.
        long retval = reader.GetBytes(0, startIndex, outByte, 0, BufferSize);

        // Continue while there are bytes beyond the size of the buffer.
        bool stillConnected = true;
        while (retval == BufferSize)
        {
            stillConnected = partialUpdateFunc(outByte, retval);
            if (!stillConnected)
            {
                break;
            }

            // Reposition start index to end of last buffer and fill buffer.
            startIndex += BufferSize;
            retval = reader.GetBytes(0, startIndex, outByte, 0, BufferSize);
        }

        // Write the remaining buffer.
        if (stillConnected)
        {
            partialUpdateFunc(outByte, retval);
        }
    }

    // Close the reader and the connection.
    reader.Close();
}