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

重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件
原文:重新想象 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("\n");}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("\n");}break;case "outputCustomHeader": // 用于显示一个自定义的 http headerResponse.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}\nBytesSent: {1}\nRetries: {2}\nStage: {3}\nTotalBytesToReceive: {4}\nTotalBytesToSend: {5}\n";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}\nBytesSent: {1}\nRetries: {2}\nStage: {3}\nTotalBytesToReceive: {4}\nTotalBytesToSend: {5}\n";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
[源码下载]

posted on 2014-09-23 13:46 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3988209.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经验贴】smartCarers在比赛后如何获取更好的发展

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 由于最近专栏开了付费,群友让更新一些经验贴,于是有了这篇文章。 一般来说,比赛完了之后是大二结束的暑假,此时有这么几条…

isset()和empty()到底区别是什么。

一招鲜吃遍天&#xff0c;自从看了燕十八关于PHP变量内部机制的那课&#xff0c;解释了一些很久的疑惑&#xff0c;知其然还知其所以然&#xff0c;果然是学习的最佳途径&#xff0c;比背下来要重要N倍。 我们知道一个变量有变量表的位置&#xff0c;然后他指向自己的内存地址&…

html清除图片缓存

img.src ?t(new Date()); 如&#xff1a; <img id "5" src"../../../pics/prod_146/__INLINE__user_nums_cmp_146.png?t"(new Date()) width"1024">

分享下自己编译 XBMC 的过程(zhuan)

刷YunOS赢魅族MX3首先要感谢下网上其他网友的经验&#xff0c;没有这些经验有的问题还是不太好解决&#xff5e; 先介绍下编译环境&#xff0c;操作系统是 CentOS 6.5 64位 (最小桌面版本安装&#xff0c;除了最基本的组件外&#xff0c;类似 java 什么的都没有安装)&#xff0…

使用Xcode和Instruments调试解决iOS内存泄露

虽然iOS 5.0版本之后加入了ARC机制&#xff0c;但由于相互引用关系比较复杂时&#xff0c;内存泄露还是可能存在。所以了解原理很重要。 这里讲述在没有ARC的情况下&#xff0c;如何使用Instruments来查找程序中的内存泄露&#xff0c;以及NSZombieEnabled设置的使用。 本文假设…

0755、0644、0600 linux文件权限

0755->即用户具有读/写/执行权限&#xff0c;组用户和其它用户具有读写权限&#xff1b; 0644->即用户具有读写权限&#xff0c;组用户和其它用户具有只读权限&#xff1b; 0600->仅拥有者具有文件的读取和写入权限

[Android] (在ScrollView里嵌套view)重叠view里面的onTouchEvent的调用方法

在我前面的自定义裁剪窗口的代码中&#xff0c;我把裁剪的view放在了大的scrollview里&#xff0c;这样就出现了程序只能触发scrollview&#xff0c;无法操作我的裁剪窗口。所以我加了那篇博客下面最后两段代码。其实我遇到这个问题的时候是在一个scrollview里添加了一个Editte…

带点击事件的Spinner

最近有一个蛋疼的需求&#xff0c;在下拉框中&#xff0c;如果只有一个值&#xff0c;默认显示出来&#xff0c;有两个或者没有显示请选择&#xff0c;没有点击不弹框&#xff0c;但是要清空&#xff0c;两个点击开要移掉请选择字样的项 本来以为很简单&#xff0c;后来发现没有…

linux进程间通信快速入门【二】:共享内存编程(mmap、XSI、POSIX)

文章目录mmap内存共享映射XSI共享内存POSIX共享内存参考使用文件或管道进行进程间通信会有很多局限性&#xff0c;比如效率问题以及数据处理使用文件描述符而不如内存地址访问方便&#xff0c;于是多个进程以共享内存的方式进行通信就成了很自然要实现的IPC方案。LInux给我们提…

ROBOTS.TXT屏蔽笔记、代码、示例大全

自己网站的ROBOTS.TXT屏蔽的记录&#xff0c;以及一些代码和示例&#xff1a; 屏蔽后台目录&#xff0c;为了安全&#xff0c;做双层管理后台目录/a/xxxx/&#xff0c;蜘蛛屏蔽/a/&#xff0c;既不透露后台路径&#xff0c;也屏蔽蜘蛛爬后台目录 缓存&#xff0c;阻止蜘蛛爬静态…

五大主流浏览器 HTML5 和 CSS3 兼容性比较

转眼又已过去了一年&#xff0c;在这一年里&#xff0c;Firefox 和 Chrome 在拼升级&#xff0c;版本号不断飙升&#xff1b;IE10 随着 Windows 8 在去年10月底正式发布&#xff0c;在 JavaScript 性能和对 HTML5 和 CSS3 的支持方面让人眼前一亮。这篇文章给大家带来《五大主流…

Ubuntu下将Sublime Text设置为默认编辑器

转自将Sublime Text 2设置为默认编辑器 修改defaults.list 编辑/etc/gnome/default.list文件&#xff0c;将其中的所有gedit.desktop替换为sublime_text.desktop。 sublime_text.desktop在/opt/sublime_text目录下&#xff0c;使用ls -al *sublime*命令查看具体文件名。 转载于…

python获取最近N天工作日列表、节假日列表

# 获取最近两周工作日列表、节假日列表 import datetime import chinese_calendar import time import pandas as pd# 将时间戳转换成格式化日期 def timestamp_to_str(timestampNone, format%Y-%m-%d %H:%M:%S):if timestamp:time_tuple time.localtime(timestamp) # 把时间…

保存页面的浏览记录

我的设计思想是将用户的浏览记录保存到cookie里面&#xff0c;然后根据情况处理。cookie里面的数据格式是json格式&#xff0c;方便根据自己的需要添加或者修改属性。引用了3个js文件,下载地址如下。 https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js …

开窍小老虎,一步一个脚印之 初识汇编(一)

最近一直浸淫在计算机编程中无法自拔。哲学 认识论中讲过。人类的求知的过程是由两次飞跃。第一是从感性认识到理性认识&#xff1b;第二是从理性认识到实践。这段话对有些人是适用的。我就是其中的一名。在知乎上求助问题“学计算机要懂汇编吗&#xff1f;”&#xff0c;地下有…

python脚本 请求数量达到上限,http请求重试

由于在内网发送http请求同一个token会限制次数&#xff0c;所以很容易达到网关流量上限。 业务中使用了多线程并发&#xff0c;一个线程发起一次http请求&#xff0c;得到正确结果后返回。这里采用的策略是&#xff0c;如果解析出来达到流量上限&#xff0c;那么该线程休眠一段…

shell 字符串操作

string"abcABC123ABCabc" 字符串长度: echo ${#string} #15 echo expr length $string #15 索引 用法&#xff1a;expr index $string $substring expr index $string "ABC" #4 提取子串 用法&#xff1a;${string:position} echo ${string:3} #A…

Linux 之目录 -鸟哥的Linux私房菜

因为利用 Linux 来开发产品或 distributions 的社群/公司与个人实在太多了, 如果每个人都用自己的想 法来配置档案放置的目录,那么将可能造成很多管理上的困扰。 你能想象,你进入一个企业之后,所 接触到的 Linux 目录配置方法竟然跟你以前学的完全不同吗? 很难想象吧~所以,后来…

python脚本:向表中插入新数据,删除表中最旧的数据

一张表存储历史数据&#xff0c;最多存储HISTORY_TABLE_MAX_ROWS条数据&#xff0c;当表中数据未达到HISTORY_TABLE_MAX_ROWS&#xff0c;直接插入&#xff1b;如果达到的话需要保证插入新数据的时候将最旧的数据删除 这里使用先update最新数据&#xff0c;然后再重新update全表…

精通 VC++ 实效编程280例 - 02 菜单和光标

菜单和关闭时重要的 Windows 资源之一。SDK 中&#xff0c;用 HCURSOR 和 HMENU 分别表示菜单和光标的句柄。MFC 中&#xff0c;CMenu 类封装了菜单的功能。 23 动态添加和删除菜单项 添加菜单项可以调用 CMenu::AppendMenu 或 CMenu::InserMenu 函数&#xff0c;删除菜单项可以…