0

J'ai essayé de mettre à jour mon pourcentage d'avancement de téléchargement pendant le téléchargement ou le téléchargement, le téléchargement n'a pas de problème du tout, cela fonctionne parfaitement. mais quand j'essaie de télécharger un fichier et essayer de mettre à jour le pourcentage de progression en attendant qu'il se termine, dès que j'ai fini de télécharger je copie le mediaStream dans un Filestream et obtient toujours un fichier vide: 0Kb. Au début, je pensais que j'avais un problème avec mon code serveur, qui est celui qui génère mon SasToken, mon nom de fichier et mon Uri.Comment puis-je réussir à copier un flux blob dans un fichier ou un flux de fichiers lors de la mise à jour de manière asynchrone?

mais cela fonctionne très bien si j'utilise blobStorage.DownloadToStreamAsync (fileStream) si j'utilise cette méthode le résultat est un fichier stocké à l'endroit voulu avec l'extension appropriée.

donc c'est mon code de test:

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

Maintenant, je suis en utilisant UWP, aussi je suis en utilisant le modèle 10 qui stimulent mon développement UWP, tout ce que je veux est d'être en mesure de télécharger l'intégralité fichier tout en montrant à mon utilisateur final la progression du téléchargement.

mais il semble que je n'ai pas encore pu le faire.

J'espère que quelqu'un peut me diriger dans la bonne direction.

Répondre

1

Eh bien, il se trouve que tout ce que je devais faire était de passer au début du flux comme celui-ci:

mediaStream.Seek(0, SeekOrigin.Begin); 
await mediaStream.CopyToAsync(fileStream); 

et à fond copie mon flux à l'endroit que je mets devant.