如何在32位应用程序上使用MemoryStream获取超过2GB的数据?

时间:2018-04-20 05:45:52

标签: c# .net web-services stream memorystream

我有以下用例。我有一个用于下载csv文件的Web服务。

Csv文件随时可以形成,即一些数据逐行从数据库中检索并在运行时转换为csv,然后将csv放入由Web服务返回的MemoryStream中下载。尽管csv文件的生成速度非常快,但它的大小可以超过2GB,当它的大小增长超过2GB OutOfMemoryException时,因为MemoryStream无法处理这么多数据。

这是我编写的测试代码片段,以更好地说明问题:

//This is my WCF WebService
public class DownloadService : IDownloadService
{
    //This is the method for download csv
    public Stream DownloadFile()
    {
        var users = GetUsers();
        using (var memoryStream = new MemoryStream())
        using (var streamWriter = new StreamWriter(memoryStream))
        {
            foreach (var user in users)
            {
                var csvRow = $"{user.Id},{user.FirstName},{user.LastName}\n";
                streamWriter.Write(csvRow);  

                //When the size exceeds 2GB exception will be thrown here
                memoryStream.Flush();
            }
            WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", $"attachment; filename=Users.csv");
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/csv";
            return memoryStream;
        }
    }

    //Method that returns Users from the database
    private IEnumerable<User> GetUsers()
    {
        string cmdQuery = "select Id, FirstName, LastName from User";
        using (var connection = new SqlConnection("some connection string"))
        using (SqlCommand cmd = new SqlCommand(cmdQuery, connection))
        {
            connection.Open();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return new User
                    {
                        Id = (int)reader["Id"],
                        FirstName = reader["FirstName"].ToString(),
                        LastName = reader["LastName"].ToString()
                    };
                }
            }
        }
    }
}

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

有什么方法可以绕过这个限制,或者可能使用另一个流?

请注意应用程序是32位,我不想使用FileStream因为,正如我所说,这一代相对较快,如果我使用FileStream,我将不得不管理所有存储和检索文件的基础设施,在我看来是多余的,也可能会减慢整个过程。

0 个答案:

没有答案