我有以下用例。我有一个用于下载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
,我将不得不管理所有存储和检索文件的基础设施,在我看来是多余的,也可能会减慢整个过程。