Datei in Blöcken herunterladen (Windows Phone)

In meiner Anwendung kann ich einige Mediendateien aus dem Internet herunterladen. Normalerweise habe ich verwendetWebClient.OpenReadCompleted Methode zum Herunterladen, Entschlüsseln und Speichern der Datei in IsolatedStorage. Es hat gut funktioniert und sah so aus:

 private void downloadedSong_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e, SomeOtherValues someOtherValues) // delegate, uses additional values
        {
            // Some preparations

                try
                {
                   if (e.Result != null)
                   {
                    using (isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        // working with the gained stream, decryption
                        // saving the decrypted file to isolatedStorage
                        isolatedStorageFileStream = new IsolatedStorageFileStream("SomeFileNameHere", FileMode.OpenOrCreate, isolatedStorageFile);
                        // and use it for MediaElement
                        mediaElement.SetSource(isolatedStorageFileStream);
                        mediaElement.Position = new TimeSpan(0);
                        mediaElement.MediaOpened += new RoutedEventHandler(mediaFile_MediaOpened);

                        // and some other work
                     }
                    }
                 }
                 catch(Exception ex) 
                 {
                  // try/catch stuff
                 }
           }

Aber nach einigen Nachforschungen fand ich heraus, dass ich bei großen Dateien (für mich sind es mehr als 100 MB) etwas bekommeOutOfMemory Ausnahme beim Herunterladen dieser Datei. Ich nehme an, das liegt daran, dass WebClient.OpenReadCompleted den gesamten Stream in den RAM lädt und drosselt ... Und ich brauche mehr Speicher, um diesen Stream zu entschlüsseln.

Nach einer anderen Untersuchung habe ich herausgefunden, wie man große Dateien nach dem OpenReadCompleted-Ereignis in Blöcke aufteilt, wenn man diese Datei in IsolatedStorage speichert (oder entschlüsselt und dann in meinem Fall speichert), aber dies würde nur bei einem Teil des Problems helfen ... Das primäre Das Problem istSo verhindern Sie Telefon-Chokes während des Download-Vorgangs. Gibt es eine Möglichkeit, große Dateien in Blöcken herunterzuladen? Dann könnte ich die gefundene Lösung verwenden, um den Entschlüsselungsprozess zu durchlaufen. (und trotzdem müsste ich einen Weg finden, um eine so große Datei in mediaElement zu laden, aber das wäre eine andere Frage)

Antworten:

 private WebHeaderCollection headers;
 private int iterator = 0;
 private int delta = 1048576;
 private string savedFile = "testFile.mp3";

 // some preparations
 // Start downloading first piece


using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (isolatedStorageFile.FileExists(savedFile))
                            isolatedStorageFile.DeleteFile(savedFile);
                    }

                    headers = new WebHeaderCollection();
                    headers[HttpRequestHeader.Range] = "bytes=" + iterator.ToString() + '-' + (iterator + delta).ToString();
                    webClientReadCompleted = new WebClient();
                    webClientReadCompleted.Headers = headers;
                    webClientReadCompleted.OpenReadCompleted += downloadedSong_OpenReadCompleted;
                    webClientReadCompleted.OpenReadAsync(new Uri(song.Link));
                    // song.Link was given earlier

private void downloadedSong_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled == false)
                {
                    if (e.Result != null)
                    {
                        ((WebClient)sender).OpenReadCompleted -= downloadedSong_OpenReadCompleted;

                        using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                        {
                            using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(savedFile, FileMode.Append, FileAccess.Write, myIsolatedStorage))
                            {
                                int mediaFileLength = (int)e.Result.Length;
                                byte[] byteFile = new byte[mediaFileLength];
                                e.Result.Read(byteFile, 0, byteFile.Length);
                                fileStream.Write(byteFile, 0, byteFile.Length); 

                                // If there's something left, download it recursively
                                if (byteFile.Length > delta)
                                {
                                    iterator = iterator + delta + 1;

                                    headers = new WebHeaderCollection();
                                    headers[HttpRequestHeader.Range] = "bytes=" + iterator.ToString() + '-' + (iterator + delta).ToString();
                                    webClientReadCompleted.Headers = headers;
                                    webClientReadCompleted.OpenReadCompleted += downloadedSong_OpenReadCompleted;
                                    webClientReadCompleted.OpenReadAsync(new Uri(song.Link));
                                }
                            }
                        }
                    }
                }
            }

Antworten auf die Frage(2)

Ihre Antwort auf die Frage