W mojej aplikacji mogę pobrać pliki multimedialne z Internetu. Zwykle używam metody pobierania, odszyfrowywania i zapisywania pliku na IsolatedStorage w celu pobrania, odszyfrowania i zapisania metody WebClient.OpenReadCompleted. To działa dobrze i wyglądał tak:Pobierz plik w kawałkach (Windows Phone)
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
}
}
Ale po jakimś dochodzeniu okazało się, że z dużymi plikami (dla mnie to więcej niż 100 MB) Dostaję OutOfMemory wyjątku podczas pobierania tego pliku. Przypuszczam, że to dlatego, że WebClient.OpenReadCompleted ładuje cały strumień do pamięci RAM i dławików ... I będę potrzebować więcej pamięci do odszyfrowania tego strumienia.
Po kolejnym dochodzeniu, znalazłem sposób dzielenia dużego pliku na porcje po zdarzeniu OpenReadCompleted podczas zapisywania tego pliku do IsolatedStorage (lub odszyfrowywania, a następnie zapisywania w mojej pamięci), ale to pomogłoby tylko w części problemu. Głównym problemem jest zapobieganie dławikom telefonicznym podczas procesu pobierania. Czy istnieje sposób na pobranie dużego pliku w porcjach? Następnie mógłbym użyć znalezionego rozwiązania do przejścia przez proces odszyfrowywania. (I nadal będę musiał znaleźć sposób, aby załadować taki duży plik do MediaElement, ale to byłoby kolejne pytanie)
Odpowiedź:
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));
}
}
}
}
}
}
pytałem ty na to pytanie? http://stackoverflow.com/questions/14600426/how-to-download-and-save-large-1gb-video-files-from-web-into-windows-phone-8/14602104#14602104 Spójrz na moje Odpowiedź –
@Hermit, nie, nie zauważyłem tego, bo nie mam Windows-phone-8 w moich ulubionych tagach. Niestety, twoja odpowiedź nie pomaga mi, teoretycznie wiem, co powinienem zrobić :) Pytanie brzmi "Jak?" – Olter
może to pomoże http://stackoverflow.com/questions/5659189/how-to-split-a-large-file-into-chunks-in-c –