uwp 下载文件显示进度并解压文件。
<Page x:Class="App4.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="909" Height="429"> <Grid > <Grid Name="gridPercent" VerticalAlignment="Top" Height="57" Margin="183,0,0,0"> <Rectangle Name="lbPercent" VerticalAlignment="Top" Height="53" Margin="0" HorizontalAlignment="Left" Width="0" Fill="Blue"/> </Grid> <TextBlock Name="txt" Foreground="Red" Text="0%" VerticalAlignment="Top" Height="53" Margin="200,0,7,0" HorizontalAlignment="Stretch"/> <Button x:Name="btnDownload" Background="WhiteSmoke" HorizontalAlignment="Left" Height="57" VerticalAlignment="Top" Width="178" Content="download" Click="BtnDownload_Click" /> </Grid> </Page>
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.Graphics.Imaging; using Windows.Storage; using Windows.Storage.Streams; using Windows.UI; using Windows.UI.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace App4 { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); Loaded += MainPage_Loaded; } private bool isDownloading = false; private async void MainPage_Loaded(object sender, RoutedEventArgs e) { } private void BtnDownload_Click(object sender, RoutedEventArgs e) { dowloadFile(); } async void dowloadFile() { if (isDownloading) return; isDownloading = true; string serverUrl = "http://files.cnblogs.com/files/pcat/hackbar.zip";//"https://files.cnblogs.com/files/wgscd/jyzsUpdate.zip"; bool isDownloadComplete = false; try { System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(serverUrl); System.Net.WebResponse response = await request.GetResponseAsync(); System.IO.Stream ns = response.GetResponseStream(); long totalSize = response.ContentLength; double hasDownSize = 0; byte[] nbytes = new byte[512];//521,2048 etc int nReadSize = 0; nReadSize = ns.Read(nbytes, 0, nbytes.Length); StorageFolder folder; folder = ApplicationData.Current.LocalFolder; string localFile = "test.zip"; StorageFile file = await folder.CreateFileAsync(localFile, CreationCollisionOption.ReplaceExisting); using (StorageStreamTransaction transaction = await file.OpenTransactedWriteAsync()) { using (DataWriter dataWriter = new DataWriter(transaction.Stream)) { while (nReadSize > 0) { dataWriter.WriteBytes(nbytes); nReadSize = ns.Read(nbytes, 0, 512); hasDownSize += nReadSize; this.Invoke(new Action(() => { txt.Text = "" + (hasDownSize / 1024.0).ToString("0.00") + " KB/" + (totalSize / 1024.0).ToString("0.00") + " KB (" + (((double)hasDownSize * 100 / totalSize).ToString("0")) + "%)";//显示下载百分比 lbPercent.Width = gridPercent.RenderSize.Width * ((double)hasDownSize / totalSize); txt.UpdateLayout(); })); } transaction.Stream.Size = await dataWriter.StoreAsync(); await dataWriter.FlushAsync(); await transaction.CommitAsync(); isDownloadComplete = true; this.Invoke(new Action(() => { txt.Text = "100%";//显示下载百分比 txt.UpdateLayout(); })); await new MessageDialog("download complete!").ShowAsync(); UnzipFile(localFile); } } } catch (Exception ex) { await new MessageDialog("download error:" + ex.ToString()).ShowAsync(); } isDownloading = false; } public async void Invoke(Action action, Windows.UI.Core.CoreDispatcherPriority Priority = Windows.UI.Core.CoreDispatcherPriority.Normal) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Priority, () => { action(); }); } private async void UnzipFile(string zipFileName) { Random rnd = new Random(); string existfile = "Elasticsearch.pptx"; var localFolder = ApplicationData.Current.LocalFolder; //路径形如:C:UsersgwangAppDataLocalPackages347b02f6-8bb6-4c2c-a494-82f3fb42f42a_px2gx6zt1mshwLocalState //尝试删除旧文件 var oldFile = await ApplicationData.Current.LocalFolder.TryGetItemAsync(existfile); if (oldFile != null) { var file = await localFolder.GetFileAsync(existfile); await file.DeleteAsync(); } //开始解压 var archive = await localFolder.GetFileAsync(zipFileName);//eg test.zip ZipFile.ExtractToDirectory(archive.Path, localFolder.Path + "\" + rnd.Next(1, 20000));//如果目标文件存在会异常 await new MessageDialog("unzip done!").ShowAsync(); } /// <summary> /// another sample, not know how to show download processs /// </summary> async void downloadFileUseHttpClient() { string serverUrl = "http://files.cnblogs.com/files/pcat/hackbar.zip"; System.Net.Http.HttpClientHandler hand = new System.Net.Http.HttpClientHandler(); // System.Net.Http.MessageProcessingHandler processMessageHander = new System.Net.Http.MessageProcessingHandler(); System.Net.Http.HttpClient localHttpClient = new System.Net.Http.HttpClient(); System.Net.Http.HttpRequestMessage httpRequestMessage = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, serverUrl); var resp = await localHttpClient.SendAsync(httpRequestMessage); Stream stream = await resp.Content.ReadAsStreamAsync(); //............ } } }
另外一种方法是利用:System.Net.Http.HttpClient
/// <summary> /// another sampe /// </summary> async void downloadFileUseHttpClient() { string serverUrl = "http://files.cnblogs.com/files/pcat/hackbar.zip"; System.Net.Http.HttpClient localHttpClient = new System.Net.Http.HttpClient(); var progress = new Progress<HttpDownloadProgress>(percent => { txt.Text =""+ percent.BytesReceived+"/"+percent.TotalBytesToReceive; txt.UpdateLayout(); }); CancellationToken token=new CancellationToken(); var data= await HttpClientExtensions.GetByteArrayAsync(localHttpClient, new Uri(serverUrl), progress, token); var folder = ApplicationData.Current.LocalFolder; string localFile = "test.zip"; StorageFile file = await folder.CreateFileAsync(localFile, CreationCollisionOption.ReplaceExisting); using (StorageStreamTransaction transaction = await file.OpenTransactedWriteAsync()) { using (DataWriter dataWriter = new DataWriter(transaction.Stream)) { dataWriter.WriteBytes(data.ToArray()); transaction.Stream.Size = await dataWriter.StoreAsync(); await dataWriter.FlushAsync(); await transaction.CommitAsync(); } } } public static class HttpClientExtensions { private const int BufferSize = 8192; public static async Task<byte[]> GetByteArrayAsync(this HttpClient client, Uri requestUri, IProgress<HttpDownloadProgress> progress, CancellationToken cancellationToken) { if (client == null) { throw new ArgumentNullException(nameof(client)); } using (var responseMessage = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)) { responseMessage.EnsureSuccessStatusCode(); var content = responseMessage.Content; if (content == null) { return Array.Empty<byte>(); } var headers = content.Headers; var contentLength = headers.ContentLength; using (var responseStream = await content.ReadAsStreamAsync().ConfigureAwait(false)) { var buffer = new byte[BufferSize]; int bytesRead; var bytes = new List<byte>(); var downloadProgress = new HttpDownloadProgress(); if (contentLength.HasValue) { downloadProgress.TotalBytesToReceive = (ulong)contentLength.Value; } progress?.Report(downloadProgress); while ((bytesRead = await responseStream.ReadAsync(buffer, 0, BufferSize, cancellationToken).ConfigureAwait(false)) > 0) { bytes.AddRange(buffer.Take(bytesRead)); downloadProgress.BytesReceived += (ulong)bytesRead; progress?.Report(downloadProgress); } return bytes.ToArray(); } } } public struct HttpDownloadProgress { public ulong BytesReceived { get; set; } public ulong? TotalBytesToReceive { get; set; } }