• 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下载。

  • 相关阅读:
    (二分查找 拓展) leetcode 69. Sqrt(x)
    (二分查找 拓展) leetcode 162. Find Peak Element && lintcode 75. Find Peak Element
    (链表) lintcode 219. Insert Node in Sorted Linked List
    (二分查找 拓展) leetcode 34. Find First and Last Position of Element in Sorted Array && lintcode 61. Search for a Range
    (最短路 Floyd) P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
    (字符串 数组 递归 双指针) leetcode 344. Reverse String
    (二叉树 DFS 递归) leetcode 112. Path Sum
    (二叉树 DFS 递归) leetcode 101. Symmetric Tree
    (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal
    (二叉树 递归 DFS) leetcode 100. Same Tree
  • 原文地址:https://www.cnblogs.com/liancs/p/2862973.html
Copyright © 2020-2023  润新知