zoukankan      html  css  js  c++  java
  • 桌面应用也可以提供HTTP文件下载

    以往,我们肯定知道,在搞Web应用的时候,我们都可能会遇到提供文件下载的功能需求,比如我以前做的一个客户许可证管理系统,客户购买ERP系统后,通常我们会根据客户的机器的机器码生成一个许可文件,而这个许可文件是有时间限制的,一年后会过期,过期之后客户需要重新获取许可,以表示继续使用我们的超级牛B产品,如果客户不再获取许可,就表明客户不再使用我们的超级牛B产品。

    后来一想,是啊,倒不如咱们弄个Web程序,让客户自行登入,输入机器码后,自动生成许可文件,然后客户在页面上点击下载就行了。提供下载功能其实很常见,像许多软件下载站等。

    不过,我们是否考虑过,如果我们编写一个仅仅提供HTTP下载相关的少数功能的应用程序,我们似乎没有必要大动干戈在机器上弄个服务器搞个Web站点。通常这种情况,做个小小的窗口程序就可以完事了。所以,就会想到使用桌面应用程序来提供HTTP下载这想法了。

    其实,这个实现起来并不复杂,System.Net命名空间下提供了一个HttpListener类,它可监听客户端传入的HTTP请求,然后返回一个HttpListenerContext对象,再通过HttpListenerContext对象可以得到用于处理请求/响应有关的对象。

    根据这个思路,我们也可以轻松做到提供下载功能,原来和Web方式是一样的,就是在响应请求时插入Content-Disposition标头,值为attachment;filename=<文件名>的方法就能实现。

    [csharp] view plain copy
     
    1. private async void btnListen_Click(object sender, EventArgs e)  
    2. {  
    3.     HttpListener listener = new HttpListener();  
    4.     listener.Prefixes.Add("http://+:80/download/");  
    5.     listener.Start();  
    6.     btnListen.Enabled = false;  
    7.     HttpListenerContext context = await listener.GetContextAsync();  
    8.     if (context != null)  
    9.     {  
    10.         // 添加Content-Disposition标头  
    11.         context.Response.AppendHeader("Content-Disposition", "attachment;filename=" + WebUtility.UrlEncode( Path.GetFileName(lblFilePath.Text)));  
    12.         try  
    13.         {  
    14.             using (FileStream stream = File.OpenRead(lblFilePath.Text))  
    15.             {  
    16.                 // 添加内容说明符  
    17.                 context.Response.ContentType = MediaTypeNames.Application.Octet;  
    18.                 // 内容长度  
    19.                 context.Response.ContentLength64 = stream.Length;  
    20.                 // 回发数据给客户端  
    21.                 byte[] buffer = new byte[1024];  
    22.                 int n = stream.Read(buffer, 0, buffer.Length);  
    23.                 while (n > 0)  
    24.                 {  
    25.                     context.Response.OutputStream.Write(buffer, 0, n);  
    26.                     n = stream.Read(buffer, 0, buffer.Length);  
    27.                 }  
    28.                 context.Response.Close(); //关闭  
    29.             }  
    30.         }  
    31.         catch(Exception ex)  
    32.         {  
    33.             MessageBox.Show(ex.Message);  
    34.         }  
    35.     }  
    36.     listener.Stop(); //停止监听  
    37.     btnListen.Enabled = true;  
    38. }  

    在设置filename时将文件名加上WebUtility.UrlEncode进行编码是防止当文件名中包含中文时呈现乱码。

    而发送文件给客户端就简单多了,和普通的流操作没有区别,把从文件中读到的数据写入Response.OutputStream流中即可,发送完毕后,调用Close方法关闭HttpListenerResponse对象,因此处理已经完成,没有必再开着它占用资源。

    监听地址为http://+:80/download/,表示HttpListener将监在80端口上的所有主机名接收到的请求,后面的路径中加上 download/ 只是为了不与IIS的默认localhost地址冲突,因为我开启了IIS。

    运行后,选择一个文件,然后点击按钮开始监听。

    随后在浏览器中输入 http://localhost/download/ ,按回车,就可以测试下载了。

  • 相关阅读:
    Cairngorm的command并不是一直存在,而是触发一次就创建一次command类的实例
    如何利用xml实现换行
    利用ViewStack实现页面的跳转
    让TextArea的垂直滚动条总是滚到对下面
    AS"文本显示和输入"探究
    fps
    简单的按键管理类,使ctrl+enter快捷键起作用
    mc的"animationComplete"事件需要冒泡吗?
    Javascript 利用键盘上的上下左右(回车)键模拟出tab 键的功能上下左右移动焦点
    DataTable操作中的性能问题(转载)
  • 原文地址:https://www.cnblogs.com/weekbo/p/8682062.html
Copyright © 2011-2022 走看看