zoukankan      html  css  js  c++  java
  • 重新想象 Windows 8.1 Store Apps (89)

    [源码下载]


    重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件



    作者:webabcd


    介绍
    重新想象 Windows 8.1 Store Apps 之通信的新特性

    • 下载数据(显示下载进度,将下载数据保存到本地)
    • 上传数据(显示上传进度)
    • 上传文件



    示例
    HTTP 服务端
    WebServer/HttpDemo.aspx.cs

    /*
     * 用于响应 http 请求
     */
    
    using System;
    using System.IO;
    using System.Threading;
    using System.Web;
    
    namespace WebServer
    {
        public partial class HttpDemo : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // 停 3 秒,以方便测试 http 请求的取消
                Thread.Sleep(3000);
    
                var action = Request.QueryString["action"];
    
                switch (action)
                {
                    case "getString": // 响应 http get string 
                        Response.Write("hello webabcd: " + DateTime.Now.ToString("hh:mm:ss"));
                        break;
                    case "getStream": // 响应 http get stream 
                        Response.Write("hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd");
                        break;
                    case "postString": // 响应 http post string 
                        Response.Write(string.Format("param1:{0}, param2:{1}, referrer:{2}", Request.Form["param1"], Request.Form["param2"], Request.UrlReferrer));
                        break;
                    case "postStream": // 响应 http post stream 
                        using (StreamReader reader = new StreamReader(Request.InputStream))
                        {
                            if (Request.InputStream.Length > 1024 * 100)
                            {
                                // 接收的数据太大,则显示“数据接收成功”
                                Response.Write("数据接收成功");
                            }
                            else
                            {
                                // 显示接收到的数据
                                string body = reader.ReadToEnd();
                                Response.Write(Server.HtmlEncode(body));
                            }
                        } 
                        break;
                    case "uploadFile": // 处理上传文件的请求
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            string key = Request.Files.GetKey(i);
                            HttpPostedFile file = Request.Files.Get(key);
                            string savePath = @"d:" + file.FileName;
    
                            // 保存文件
                            file.SaveAs(savePath);
    
                            Response.Write(string.Format("key: {0}, fileName: {1}, savePath: {2}", key, file.FileName, savePath));
                            Response.Write("
    ");
                        }
                        break;
                    case "outputCookie": // 用于显示服务端获取到的 cookie 信息
                        for (int i = 0; i < Request.Cookies.Count; i++)
                        {
                            HttpCookie cookie = Request.Cookies[0];
                            Response.Write(string.Format("cookieName: {0}, cookieValue: {1}", cookie.Name, cookie.Value));
                            Response.Write("
    ");
                        }
                        break;
                    case "outputCustomHeader": // 用于显示一个自定义的 http header
                        Response.Write("myRequestHeader: " + Request.Headers["myRequestHeader"]);
                        break;
                    default:
                        break;
                }
    
                Response.End();
            }
        }
    }


    1、演示如何通过新的 HttpClient(Windows.Web.Http)获取下载进度,并将下载数据保存到本地
    Download.xaml.cs

    /*
     * 本例演示如何通过新的 HttpClient(Windows.Web.Http)获取下载进度,并将下载数据保存到本地
     * 
     * 
     * 注:在 win8 时代要想获取下载进度只能依靠后台任务来完成
     */
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Windows.Storage;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    using Windows.Web.Http;
    
    namespace Windows81.Communication.HTTP
    {
        public sealed partial class Download : Page
        {
            private HttpClient _httpClient;
            private CancellationTokenSource _cts;
    
            public Download()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 释放资源
                if (_httpClient != null)
                {
                    _httpClient.Dispose();
                    _httpClient = null;
                }
    
                if (_cts != null)
                {
                    _cts.Dispose();
                    _cts = null;
                }
            }
    
            private async void btnDownload_Click(object sender, RoutedEventArgs e)
            {
                _httpClient = new HttpClient();
                _cts = new CancellationTokenSource();
    
                try
                {
                    // 用于获取下载进度
                    IProgress<HttpProgress> progress = new Progress<HttpProgress>(ProgressHandler);
    
                    HttpResponseMessage response = await _httpClient.GetAsync(
                        new Uri("http://files.cnblogs.com/webabcd/WindowsPhone.rar?ll"),
                        HttpCompletionOption.ResponseContentRead).AsTask(_cts.Token, progress); // 把 progress 放到 task 里,以便获取下载进度
    
                    lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                    lblMsg.Text += Environment.NewLine;
    
                    // 将下载好的数据保存到本地
                    StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
                    StorageFile storageFile = await storageFolder.CreateFileAsync("WindowsPhone.rar", CreationCollisionOption.ReplaceExisting);
                    using (StorageStreamTransaction transaction = await storageFile.OpenTransactedWriteAsync())
                    {
                        lblMsg.Text = "文件已下载,写入到磁盘中...";
    
                        /*
                         * IHttpContent.WriteToStreamAsync() - 用于保存数据
                         */
                        await response.Content.WriteToStreamAsync(transaction.Stream);
                        await transaction.CommitAsync();
    
                        lblMsg.Text = "文件已写入到磁盘";
                    }
                }
                catch (TaskCanceledException)
                {
                    lblMsg.Text += "取消了";
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            private void btnCancel_Click(object sender, RoutedEventArgs e)
            {
                // 取消 http 请求
                if (_cts != null)
                {
                    _cts.Cancel();
                    _cts.Dispose();
                    _cts = null;
                }
            }
    
            // 下载进度发生变化时调用的处理器
            private void ProgressHandler(HttpProgress progress)
            {
                /*
                 * HttpProgress - http 通信的进度
                 *     BytesReceived - 已收到的字节数
                 *     BytesSent - 已发送的字节数
                 *     TotalBytesToReceive - 总共需要收到的字节数
                 *     TotalBytesToSend - 总共需要发送的字节数
                 *     Retries - 重试次数
                 *     Stage - 当前通信的阶段(HttpProgressStage 枚举)
                 */
    
                string result = "BytesReceived: {0}
    BytesSent: {1}
    Retries: {2}
    Stage: {3}
    TotalBytesToReceive: {4}
    TotalBytesToSend: {5}
    ";
                result = string.Format(result, progress.BytesReceived, progress.BytesSent, progress.Retries, progress.Stage, progress.TotalBytesToReceive, progress.TotalBytesToSend);
    
                lblMsg.Text = result;
            }
        }
    }


    2、演示如何通过新的 HttpClient(Windows.Web.Http)获取上传进度
    Upload.xaml.cs

    /*
     * 本例演示如何通过新的 HttpClient(Windows.Web.Http)获取上传进度
     * 
     * 
     * 注:在 win8 时代要想获取上传进度只能依靠后台任务来完成
     */
    
    using System;
    using System.IO;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Threading;
    using System.Threading.Tasks;
    using Windows.Foundation;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    using Windows.Web.Http;
    
    namespace Windows81.Communication.HTTP
    {
        public sealed partial class Upload : Page
        {
            private HttpClient _httpClient;
            private CancellationTokenSource _cts;
    
            public Upload()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 释放资源
                if (_httpClient != null)
                {
                    _httpClient.Dispose();
                    _httpClient = null;
                }
    
                if (_cts != null)
                {
                    _cts.Dispose();
                    _cts = null;
                }
            }
    
            private async void btnUpload_Click(object sender, RoutedEventArgs e)
            {
                _httpClient = new HttpClient();
                _cts = new CancellationTokenSource();
    
                try
                {
                    Uri resourceAddress = new Uri("http://localhost:39630/HttpDemo.aspx?action=postStream");
    
                    // 模拟一个比较大的比较慢的流,供 http 上传
                    const uint streamLength = 10000000;
                    HttpStreamContent streamContent = new HttpStreamContent(new SlowInputStream(streamLength));
                    streamContent.Headers.ContentLength = streamLength; // 必须要指定请求数据的 ContentLength,否则就是 chunked 了
    
                    // 用于获取上传进度
                    IProgress<HttpProgress> progress = new Progress<HttpProgress>(ProgressHandler);
    
                    HttpResponseMessage response = await _httpClient.PostAsync(resourceAddress, streamContent).AsTask(_cts.Token, progress); // 把 progress 放到 task 里,以便获取上传进度
    
                    lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                    lblMsg.Text += Environment.NewLine;
    
                    lblMsg.Text += await response.Content.ReadAsStringAsync();
                    lblMsg.Text += Environment.NewLine;
                }
                catch (TaskCanceledException)
                {
                    lblMsg.Text += "取消了";
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            // 生成一个指定大小的内存流
            private static MemoryStream GenerateSampleStream(int size)
            {
                byte[] subData = new byte[size];
                for (int i = 0; i < subData.Length; i++)
                {
                    subData[i] = (byte)(97 + i % 26); // a-z
                }
    
                return new MemoryStream(subData);
            }
    
            private void btnCancel_Click(object sender, RoutedEventArgs e)
            {
                // 取消 http 请求
                if (_cts != null)
                {
                    _cts.Cancel();
                    _cts.Dispose();
                    _cts = null;
                }
            }
    
            // 上传进度发生变化时调用的处理器
            private void ProgressHandler(HttpProgress progress)
            {
                /*
                 * HttpProgress - http 通信的进度
                 *     BytesReceived - 已收到的字节数
                 *     BytesSent - 已发送的字节数
                 *     TotalBytesToReceive - 总共需要收到的字节数
                 *     TotalBytesToSend - 总共需要发送的字节数
                 *     Retries - 重试次数
                 *     Stage - 当前通信的阶段(HttpProgressStage 枚举)
                 */
    
                string result = "BytesReceived: {0}
    BytesSent: {1}
    Retries: {2}
    Stage: {3}
    TotalBytesToReceive: {4}
    TotalBytesToSend: {5}
    ";
                result = string.Format(result, progress.BytesReceived, progress.BytesSent, progress.Retries, progress.Stage, progress.TotalBytesToReceive, progress.TotalBytesToSend);
    
                lblMsg.Text = result;
            }
        }
    
    
        // 模拟一个比较慢的输入流
        class SlowInputStream : IInputStream
        {
            uint length;
            uint position;
    
            public SlowInputStream(uint length)
            {
                this.length = length;
                position = 0;
            }
    
            public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
            {
                return AsyncInfo.Run<IBuffer, uint>(async (cancellationToken, progress) =>
                {
                    if (length - position < count)
                    {
                        count = length - position;
                    }
    
                    byte[] data = new byte[count];
                    for (uint i = 0; i < count; i++)
                    {
                        data[i] = 64;
                    }
    
                    // 延迟 10 毫秒再继续,以模拟一个比较慢的输入流
                    await Task.Delay(10);
    
                    position += count;
                    progress.Report(count);
    
                    return data.AsBuffer();
                });
            }
    
            public void Dispose()
            {
    
            }
        }
    }


    3、演示如何通过新的 HttpClient(Windows.Web.Http)上传文件(通过 multipart/form-data 的方式)
    UploadFile.xaml.cs

    /*
     * 本例演示如何通过新的 HttpClient(Windows.Web.Http)上传文件(通过 multipart/form-data 的方式)
     */
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Windows.Storage;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    using Windows.Web.Http;
    
    namespace Windows81.Communication.HTTP
    {
        public sealed partial class UploadFile : Page
        {
            private HttpClient _httpClient;
            private CancellationTokenSource _cts;
    
            public UploadFile()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 释放资源
                if (_httpClient != null)
                {
                    _httpClient.Dispose();
                    _httpClient = null;
                }
    
                if (_cts != null)
                {
                    _cts.Dispose();
                    _cts = null;
                }
            }
    
            private async void btnUploadFile_Click(object sender, RoutedEventArgs e)
            {
                _httpClient = new HttpClient();
                _cts = new CancellationTokenSource();
    
                try
                {
                    // 构造需要上传的文件数据
                    StorageFile file1 = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Son.jpg", UriKind.Absolute));
                    IRandomAccessStreamWithContentType stream1 = await file1.OpenReadAsync();
                    HttpStreamContent streamContent1 = new HttpStreamContent(stream1);
    
                    // 构造需要上传的文件数据
                    StorageFile file2 = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Son.jpg", UriKind.Absolute));
                    IRandomAccessStreamWithContentType stream2 = await file1.OpenReadAsync();
                    HttpStreamContent streamContent2 = new HttpStreamContent(stream2);
    
                    // 通过 HttpMultipartFormDataContent 来指定需要“multipart/form-data”上传的文件
                    HttpMultipartFormDataContent fileContent = new HttpMultipartFormDataContent();
                    // 第 1 个参数:需要上传的文件数据
                    // 第 2 个参数:对应 asp.net 服务的 Request.Files 中的 key(参见:WebServer 项目中的 HttpDemo.aspx.cs)
                    // 第 3 个参数:对应 asp.net 服务的 Request.Files 中的 fileName(参见:WebServer 项目中的 HttpDemo.aspx.cs)
                    fileContent.Add(streamContent1, "file1", "file1.jpg"); 
                    fileContent.Add(streamContent2, "file2", "file2.jpg");
    
                    HttpResponseMessage response = await _httpClient.PostAsync(new Uri("http://localhost:39630/HttpDemo.aspx?action=uploadFile"), fileContent).AsTask(_cts.Token);
    
                    lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                    lblMsg.Text += Environment.NewLine;
    
                    lblMsg.Text += await response.Content.ReadAsStringAsync();
                    lblMsg.Text += Environment.NewLine;
                }
                catch (TaskCanceledException)
                {
                    lblMsg.Text += "取消了";
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            private void btnCancel_Click(object sender, RoutedEventArgs e)
            {
                // 取消 http 请求
                if (_cts != null)
                {
                    _cts.Cancel();
                    _cts.Dispose();
                    _cts = null;
                }
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    Python--面向对象编程(2)
    Python--面向对象编程(1)
    Python--常用模块
    Python--函数
    Hadoop综合大作业
    hive基本操作与应用
    MapReduce作业
    熟悉HBase基本操作
    熟悉常用的HDFS操作
    爬虫大作业(对电影的爬取)
  • 原文地址:https://www.cnblogs.com/webabcd/p/3904464.html
Copyright © 2011-2022 走看看