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; }
}