SqlFileStream:在 HTTP 响应中返回流与字节数组

Dra*_*aco 5 arrays httpresponse filestream asp.net-web-api asp.net-web-api2

我对使用 .net Web API 在 HTTP 响应中返回字节数组与流的问题有点困惑。

我遇到了以下代码:

        SqlConnection conn = new SqlConnection();
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "Select FileData.PathName() As FilePath, GET_FILESTREAM_TRANSACTION_CONTEXT() AS Context From FileStorage";
        conn.Open();
        SqlDataReader reader = cmd.ExecuteReader();
        reader.Read();
        string filePath = (string)reader["FilePath"];

        byte[] fileBytes = (byte[])reader["Context"];
        SqlFileStream stream = new SqlFileStream(filePath, fileBytes, FileAccess.Read);

        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
Run Code Online (Sandbox Code Playgroud)

问题 1: 为什么他们会在 HTTP 响应中返回 Stream 而不是字节数组?

问题2:如果通过调用已经可以使用字节数组 ,为什么还要创建SqlFileStream来读取数据(byte[])reader["Context"]?这不是意味着整个文件内容都被读入内存吗?那么为什么需要 Stream 呢?

Mik*_*kis 5

问题 1:为什么他们会在 HTTP 响应中返回 Stream 而不是字节数组?

因为字节数组可能很大,所以如果将整个数组读入服务器的内存中并将其保留在内存中直到全部传输到客户端,则会给服务器带来巨大的内存负担。这就是拒绝服务攻击的组成部分。通过使用流,您允许服务器根据需要以小块的形式加载数据,并在任何给定时间仅在内存中保留一小块数据,同时等待数据传输。

问题2:如果通过调用(byte[])reader["Context"]已经可以使用字节数组,为什么还要创建SqlFileStream来读取数据?这不是意味着整个文件内容都被读入内存吗?那么为什么需要 Stream 呢?

您看到的字节数组不是实际的文件内容。如果您查看 的构造函数的文档SqlFileStream以及该类文档SqlFileStream,您会发现这个字节数组是一些“事务上下文”,这是数据库服务器从存储中读取实际数据所必需的(一个可怕的黑客)。实际数据可能很大,因此您发布的代码会执行所有这些操作,以避免将其全部加载到内存中。