重新想象 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.pswp.cn/news/376630.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376630.shtml
英文地址,請注明出處:http://en.pswp.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;刪除菜單項可以…