【发布时间】:2011-08-27 20:48:09
【问题描述】:
在我的 Silverlight 应用程序中,我需要下载大文件。我目前通过在托管 Silverlight 应用程序的同一服务器上调用 ASPX 页面来从字节数组中流式传输这些数据。 ASPX Page_Load() 方法如下所示:
protected void Page_Load(object sender, EventArgs e)
{
// we are sending binary data, not HTML/CSS, so clear the page headers
Response.Clear();
Response.ContentType = "Application/xod";
string filePath = Request["file"]; // passed in from Silverlight app
// ...
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// send data 30 KB at a time
Byte[] t = new Byte[30 * 1024];
int bytesRead = 0;
bytesRead = fs.Read(t, 0, t.Length);
Response.BufferOutput = false;
int totalBytesSent = 0;
Debug.WriteLine("Commence streaming...");
while (bytesRead > 0)
{
// write bytes to the response stream
Response.BinaryWrite(t);
// write to output how many bytes have been sent
totalBytesSent += bytesRead;
Debug.WriteLine("Server sent total " + totalBytesSent + " bytes.");
// read next bytes
bytesRead = fs.Read(t, 0, t.Length);
}
}
Debug.WriteLine("Done.");
// ensure all bytes have been sent and stop execution
Response.End();
}
从 Silverlight 应用程序,我只是将 uri 交给读取字节数组的对象:
Uri uri = new Uri("https://localhost:44300/TestDir/StreamDoc.aspx?file=" + path);
我的问题是......如果用户取消,我该如何停止这个流?就像现在一样,如果用户选择另一个文件来下载,新的流将开始,前一个流将继续流,直到完成。
一旦流开始,我找不到中止流的方法。
非常感谢任何帮助。
-斯科特
【问题讨论】:
-
除此之外,您总是假设 Read 调用会填满缓冲区,因为您随后会写出整个缓冲区而不是刚刚读取的字节。
-
不确定我是否遵循,但缓冲区中永远不会超过 30k,是的,然后我将整个 30k(或更少)发送回响应通道。
-
但其中的有用数据可能少于 30K。您应该只在每次迭代中写入
bytesRead字节,而不是整个 30K。 -
啊,我明白你现在在说什么了。好眼光 - 我会努力解决这个问题。实际上,我对它的工作感到有点震惊,因为读取的字节和每次迭代的 30k 限制之间可能存在垃圾。我猜我很“幸运”,并且在我的测试中每次都读取了完整的 30k。
-
从本地磁盘读取通常会填满缓冲区。但是你的最后一次迭代几乎总是错误的——你可能有很多文件都有尾随垃圾,事实上。当然,在某些文件格式中并不重要。
标签: asp.net silverlight stream