I have been trying to update my download percent advance while downloading or uploading, uploading doesnt have a trouble at all, it works perfectly. but when I try to download a file and try to update the percent progress while waiting for it to end, as soon as I ended to download I copy the mediaStream to a Filestream an always get as a result an empty file: 0Kb.
at beginning I thought i had something wrong with my server side code, which is the one to generate my SasToken, filename and Uri.
but it works fine if I use blobStorage.DownloadToStreamAsync(fileStream) if I use that method the result is a file stored at the place I wanted with the proper extension.
so this is my testing code:
private async Task ExecuteDownloadFileCommand()
{
var busyView = new Busy();
busyView.IsBusy = true;
Busy.SetBusy(busyView.IsBusy, $"Please Wait...\nDownloading: {FileProgress * 100}");
try
{
// Get the SAS token from the backend
ICloudService cloudService = ServiceLocator.Instance.Resolve<ICloudService>();
var storageToken = await cloudService.GetSasTokenAsync("7ec0d415c1994082a954ae6329b02915");
// Use the SAS token to get a reference to the blob storage
var storageUri = new Uri($"{storageToken.Uri}{storageToken.SasToken}");
var blobStorage = new CloudBlockBlob(storageUri);
//Organize the store file process.
var storageFolder = await StorageFolder.GetFolderFromPathAsync(ApplicationData.Current.TemporaryFolder.Path);
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
savePicker.FileTypeChoices.Add("Picture", new List<string> { ".jpg" });
savePicker.SuggestedFileName = "photo.jpg";
var storageDestinationFile = await savePicker.PickSaveFileAsync();
FileStream fileStream = null;
await Task.Run(() =>
{
fileStream = File.Create(storageDestinationFile.Path);
});
//await blobStorage.DownloadToStreamAsync(fileStream); //this line of code gives me the result i want.
using (var mediaStream = await blobStorage.OpenReadAsync())
{
var bytesInBlocks = 1024;
var mediaLength = mediaStream.Length;
byte[] buffer = new byte[bytesInBlocks];
var bytesRead = 0;
double totalBytesRead = 0.0;
var blocksRead = 0;
var blockIds = new List<string>();
IsDownloadingFile = true;
FileProgress = 0.0;
// Do what you need to for opening your output file
do
{
bytesRead = await mediaStream.ReadAsync(buffer, 0, bytesInBlocks);
if (bytesRead > 0)
{
//Update the interval counters
totalBytesRead += bytesRead;
blocksRead++;
//Update the progress bar.
var progress = totalBytesRead / mediaLength;
FileProgress = progress;
Busy.SetBusy(busyView.IsBusy, $"Please Wait... \nDownloading: {FileProgress * 100}");
}
} while (bytesRead > 0);
mediaStream.CopyTo(fileStream); //this line of code isnt copying anything.
//using (var mediaRandomAccessStream = mediaStream.AsRandomAccessStream())
//{
// using (var mediaInputStream = mediaRandomAccessStream.GetInputStreamAt(0)) //this line of code throws and exception because the randomaccess code cant be clone.
// {
// using (var destinationStream = await storageDestinationFile.OpenAsync(FileAccessMode.ReadWrite))
// {
// using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
// {
// await RandomAccessStream.CopyAndCloseAsync(mediaRandomAccessStream, destinationOutputStream);
// }
// }
// }
//}
}
fileStream.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine($"[TaskListViewModel] Downloading error: {ex.Message}");
}
finally
{
busyView.IsBusy = false;
IsDownloadingFile = false;
FileProgress = 0.0;
Busy.SetBusy(busyView.IsBusy);
}
}
Now I'm using UWP, also I'm using template 10 which boost my development in UWP, all i want is to be able to fully download a file while showing my end user the download progress.
but it seems I havent been able to do it just yet.
hopefully someone can point me in the right direction.
Well it turns out that all i needed to do was to move to the beginning of the stream like this:
mediaStream.Seek(0, SeekOrigin.Begin);
await mediaStream.CopyToAsync(fileStream);
and it fully copies my stream to the place I set before.