Silverlight 实现文件下载

文件下载通常采用附件的方式在http响应头里面设置Content-disposition值为"attachment;filename=" + filepath,以及为Content-Length设置下载文件总长度(单位字节)来实现。
本文是采用Silverlight实现文件下载,服务端用asp.net一般处理程序(.ashx)处理。
以下是项目结构图:

MainPage类源码如下:

View Code
  1 namespace SilverlightDownAndUploadFile
  2 {
  3     public delegate void SaveFileHandler(int bytesRead, byte[] buffer);
  4     public delegate void UploadFileHandler(int bytesRead);
  5     public partial class MainPage : UserControl
  6     {
  7         private SaveFileDialog sfd;
  8         private OpenFileDialog ofd;
  9         Stream stream = null;
 10         BinaryWriter bw = null;
 11         private long fileLen = 0;
 12         private long readFileLen = 0;//已下载长度
 13         private AutoResetEvent autoEvent = new AutoResetEvent(false);
 14 
 15         public MainPage()
 16         {
 17             InitializeComponent();
 18         }
 19 
 20         #region 下载
 21         private void ShowDownResult(bool isSuccess)
 22         {
 23             this.Dispatcher.BeginInvoke(
 24                 () =>
 25                 {
 26                     if (isSuccess)
 27                         MessageBox.Show("下载完毕.");
 28                     else
 29                         MessageBox.Show("下载出错!");
 30                 });
 31         }
 32 
 33         private void UpdateDownProgress(int bytesRead)
 34         {
 35             readFileLen += bytesRead;
 36 
 37             double rate = Convert.ToDouble(readFileLen) / Convert.ToDouble(fileLen);
 38             double percent = Math.Round(rate, 2) * 100;
 39             downProgress.Visibility = Visibility.Visible;
 40             downProgress.pgBar.Value = percent;
 41             downProgress.txtProgress.Text = percent + "%";
 42 
 43         }
 44 
 45         private void FlushToFile(int bytesRead, byte[] buffer)
 46         {
 47             try
 48             {
 49                 if (null == stream)
 50                 {
 51                     stream = sfd.OpenFile();
 52                     bw = new BinaryWriter(stream);
 53                 }
 54 
 55                 bw.Write(buffer, 0, bytesRead);
 56                 bw.Flush();
 57                 UpdateDownProgress(bytesRead);
 58                 autoEvent.Set();
 59             }
 60             catch (Exception ex)
 61             { }
 62         }
 63 
 64         private void RequestAndDownFile()
 65         {
 66             try
 67             {
 68                 HttpWebRequest request = CreateWebRequest("http://localhost:13953/Download.ashx", "GET");
 69                 HttpWebRequest webRequest = request;
 70                 webRequest.BeginGetResponse(
 71                             (asyncResult) =>
 72                             {
 73                                 if (webRequest.HaveResponse)
 74                                 {
 75                                     try
 76                                     {
 77                                         WebResponse response = webRequest.EndGetResponse(asyncResult);//易发生异常
 78                                         fileLen = Convert.ToInt64(response.Headers["Content-Length"]);//文件长度
 79 
 80                                         Stream responseStream = response.GetResponseStream();
 81                                         int maxBufLength = 20 * 1024;//20K
 82                                         byte[] buffer = new byte[maxBufLength];
 83                                         int bytesRead = responseStream.Read(buffer, 0, maxBufLength);
 84                                         while (bytesRead != 0)
 85                                         {
 86                                             Dispatcher.BeginInvoke(new SaveFileHandler(FlushToFile), bytesRead, buffer);
 87                                             autoEvent.WaitOne();
 88                                             buffer = new byte[maxBufLength];
 89                                             bytesRead = responseStream.Read(buffer, 0, maxBufLength);
 90                                         }
 91 
 92                                         ShowDownResult(true);
 93                                     }
 94                                     catch (Exception ex)
 95                                     {
 96                                         ShowDownResult(false);
 97                                     }
 98                                     finally
 99                                     {
100                                         this.Dispatcher.BeginInvoke(
101                                             () =>
102                                             {
103                                                 if (null != bw)
104                                                     bw.Close();
105                                                 if (null != stream)
106                                                     stream.Close();
107                                             });
108                                     }
109                                 }
110                             }, null);
111 
112             }
113             catch (Exception ex)
114             {
115                 ShowDownResult(false);
116             }
117         }
118 
119         private void btnDownload_Click(object sender, RoutedEventArgs e)
120         {
121             fileLen = 0;
122             readFileLen = 0;
123             sfd = new SaveFileDialog();
124             sfd.Filter = "(*.rar)|*.rar";
125 
126             if (sfd.ShowDialog() == true)
127             {
128                 RequestAndDownFile();
129             }
130         }
131 
132         private static HttpWebRequest CreateWebRequest(string requestUriString, string httpMethod)
133         {
134             try
135             {
136                 string ticks = Guid.NewGuid().ToString();
137                 requestUriString = requestUriString + "/" + ticks;
138                 HttpWebRequest request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(requestUriString));
139                 request.Method = httpMethod;
140 
141                 return request;
142             }
143             catch (Exception ex)
144             {
145                 return null;
146             }
147         }
148         #endregion
149 
150         /// <summary>
151         /// 获了实际接读取到的字节数组
152         /// </summary>
153         /// <param name="buffer"></param>
154         /// <param name="bytesRead"></param>
155         /// <returns></returns>
156         private byte[] GetNewBuffer(byte[] buffer, int bytesRead)
157         {
158             byte[] newBuffer = new byte[bytesRead];
159             for (int i = 0; i < bytesRead; i++)
160             {
161                 newBuffer[i] = buffer[i];
162             }
163             return newBuffer;
164         }
165     }

Download.ashx源码如下:

View Code
 1 namespace SilverlightDownAndUploadFile.Web
 2 {
 3     /// <summary>
 4     /// Download 的摘要说明
 5     /// </summary>
 6     public class Download : IHttpHandler
 7     {
 8 
 9         public void ProcessRequest(HttpContext context)
10         {
11             try
12             {
13                 //context.Response.ContentType = "text/plain";
14                 //context.Response.Write("Hello World");
15                 //要下载文件路径
16                 string path = "d:/test.rar"; //context.Server.MapPath("~/Files/lan.txt");
17                 context.Response.ContentType = Utils.GetContentType(path);//设置ContentType
18                 context.Response.AppendHeader("Content-disposition", "attachment;filename=" + path);
19                 context.Response.BufferOutput = false;
20                 context.Response.Buffer = false;
21                 using (FileStream fs = File.OpenRead(path))
22                 {
23                     BinaryReader br = new BinaryReader(fs);
24                     long fileLen = br.BaseStream.Length;
25                     context.Response.AppendHeader("Content-Length", fileLen.ToString());
26 
27                     int bytesRead = 0;//读取到的字节数
28                     int maxBufLength = 20 * 1024;//20K
29                     byte[] buffer = new byte[maxBufLength];
30                     bytesRead = br.Read(buffer, 0, maxBufLength);
31                     while (bytesRead != 0)
32                     {
33                         byte[] newBuffer = GetNewBuffer(buffer, bytesRead);
34                         context.Response.BinaryWrite(newBuffer);
35                         context.Response.Flush();
36                         buffer = new byte[maxBufLength];
37                         bytesRead = br.Read(buffer, 0, maxBufLength);
38                     }
39                     context.Response.Flush();
40                     context.Response.End();
41                 }
42             }
43             catch (Exception ex)
44             {
45 
46             }
47         }
48 
49         /// <summary>
50         /// 获了实际接读取到的字节数组
51         /// </summary>
52         /// <param name="buffer"></param>
53         /// <param name="bytesRead"></param>
54         /// <returns></returns>
55         private byte[] GetNewBuffer(byte[] buffer, int bytesRead)
56         {
57             byte[] newBuffer = new byte[bytesRead];
58             for (int i = 0; i < bytesRead; i++)
59             {
60                 newBuffer[i] = buffer[i];
61             }
62             return newBuffer;
63         }
64 
65         public bool IsReusable
66         {
67             get
68             {
69                 return false;
70             }
71         }
72     }
73 }

完整项目源码可从http://download.csdn.net/detail/lianchangshuai/4998494下载。

posted @ 2013-01-16 16:20  liancs  阅读(988)  评论(0编辑  收藏  举报