2014-02-16 3 views

ответ

5

Загрузка файла является огромным предметом и может быть выполнена разными способами. Я предполагаю, что вы знаете файл Uri файла, который хотите загрузить, и хотите, чтобы вы имели в виду: local is IsolatedStorage.

Я покажу три примера, как это можно сделать (есть и другие способы).

1. Простейший пример будет Dowload строку через WebClient:

public static void DownloadFileVerySimle(Uri fileAdress, string fileName) 
{ 
    WebClient client = new WebClient(); 
    client.DownloadStringCompleted += (s, ev) => 
    { 
     using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication()) 
     using (StreamWriter writeToFile = new StreamWriter(ISF.CreateFile(fileName))) 
      writeToFile.Write(ev.Result); 
    }; 
    client.DownloadStringAsync(fileAdress); 
} 

Как вы можете видеть, я непосредственно загружая строку (ev.Result является string - то есть disadventage этого метода) в IsolatedStorage , А использование - например, после нажатия кнопки мыши:

private void Download_Click(object sender, RoutedEventArgs e) 
{ 
    DownloadFileVerySimle(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt"); 
} 

2. Во втором методе (простой, но более сложный) я буду использовать снова WebClient и я должен сделать это асинхронно (если вы но к этому я бы предложил прочитать MSDN, async-await on Stephen Cleary blog и, возможно, некоторые tutorials).

Сначала мне нужно Task который загрузит Stream из сети:

public static Task<Stream> DownloadStream(Uri url) 
{ 
    TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream>(); 
    WebClient wbc = new WebClient(); 
    wbc.OpenReadCompleted += (s, e) => 
    { 
     if (e.Error != null) tcs.TrySetException(e.Error); 
     else if (e.Cancelled) tcs.TrySetCanceled(); 
     else tcs.TrySetResult(e.Result); 
    }; 
    wbc.OpenReadAsync(url); 
    return tcs.Task; 
} 

Тогда я напишу мой метод загрузки файла - он также должен быть асинхронной, как я буду использовать Await DownloadStream:

public enum DownloadStatus { Ok, Error }; 

public static async Task<DownloadStatus> DownloadFileSimle(Uri fileAdress, string fileName) 
{ 
    try 
    { 
     using (Stream resopnse = await DownloadStream(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute))) 
     using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication()) 
     { 
      if (ISF.FileExists(fileName)) return DownloadStatus.Error; 
      using (IsolatedStorageFileStream file = ISF.CreateFile(fileName)) 
       resopnse.CopyTo(file, 1024); 
      return DownloadStatus.Ok; 
     } 
    } 
    catch { return DownloadStatus.Error; } 
} 

А использование моего метода, например, после нажатия кнопки мыши:

private async void Downlaod_Click(object sender, RoutedEventArgs e) 
{ 
    DownloadStatus fileDownloaded = await DownloadFileSimle(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt"); 
    switch (fileDownloaded) 
    { 
     case DownloadStatus.Ok: 
      MessageBox.Show("File downloaded!"); 
      break; 
     case DownloadStatus.Error: 
     default: 
      MessageBox.Show("There was an error while downloading."); 
      break; 
    } 
} 

Этот метод может иметь проблемы, например, если вы пытаетесь загрузить очень большой файл (пример 150 Мб).

3. Третий метод - использует WebRequest с асинхронным снова-ЖДИТЕ, но этот метод может быть изменен для загрузки файлов через буфер, и, следовательно, не использовать слишком много памяти:

Во-первых, мне нужно чтобы продлить свое Webrequest способом, который будет асинхронно возвращать Stream:

public static class Extensions 
{ 
    public static Task<Stream> GetRequestStreamAsync(this WebRequest webRequest) 
    { 
     TaskCompletionSource<Stream> taskComplete = new TaskCompletionSource<Stream>(); 
     webRequest.BeginGetRequestStream(arg => 
     { 
      try 
      { 
       Stream requestStream = webRequest.EndGetRequestStream(arg); 
       taskComplete.TrySetResult(requestStream); 
      } 
      catch (Exception ex) { taskComplete.SetException(ex); } 
     }, webRequest); 
     return taskComplete.Task; 
    } 
} 

Тогда я могу работать и написать свой метод Выгрузка:

public static async Task<DownloadStatus> DownloadFile(Uri fileAdress, string fileName) 
{ 
    try 
    { 
     WebRequest request = WebRequest.Create(fileAdress); 
     if (request != null) 
     { 
      using (Stream resopnse = await request.GetRequestStreamAsync()) 
      { 
      using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
        if (ISF.FileExists(fileName)) return DownloadStatus.Error; 
        using (IsolatedStorageFileStream file = ISF.CreateFile(fileName)) 
        { 
         const int BUFFER_SIZE = 10 * 1024; 
         byte[] buf = new byte[BUFFER_SIZE]; 

         int bytesread = 0; 
         while ((bytesread = await resopnse.ReadAsync(buf, 0, BUFFER_SIZE)) > 0) 
           file.Write(buf, 0, bytesread); 
        } 
      } 
      return DownloadStatus.Ok; 
     } 
    } 
    return DownloadStatus.Error; 
    } 
    catch { return DownloadStatus.Error; } 
} 

Снова использование:

private async void Downlaod_Click(object sender, RoutedEventArgs e) 
{ 
    DownloadStatus fileDownloaded = await DownloadFile(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt"); 
    switch (fileDownloaded) 
    { 
     case DownloadStatus.Ok: 
      MessageBox.Show("File downloaded!"); 
      break; 
     case DownloadStatus.Error: 
     default: 
      MessageBox.Show("There was an error while downloading."); 
      break; 
    } 
} 

Эти методы, конечно, может быть улучшен, но я думаю, что это может дать вам обзор, как это может выглядеть. Основным недостатком этих методов может быть то, что они работают на переднем плане, а это означает, что когда вы выходите из приложения или запускаете кнопку запуска, загрузка останавливается.Если вам нужно скачать в фоновом режиме, вы можете использовать Background File Transfers - но это другая история.

Как вы можете видеть, вы можете достичь своей цели разными способами. Вы можете больше узнать об этих методах на многих страницах, учебниках и блогах, сравните выбрать наиболее подходящий.

Надеюсь, это поможет. Счастливое кодирование и удачи.

+0

Спасибо Romasz. Можете ли вы показать мне, где находится папка IsolatedStorage на моем компьютере после сохранения этого файла. – Carson

+2

@Carson IsolatedStorage папка находится в вашем телефоне, это «место», строго связанное с вашим приложением, и никакое другое приложение не имеет к нему доступа. Однако вы можете с уверенностью изучить свое устройство разработчика (или эмулятор) с помощью [Изолированный хранилище Explorer] (http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh286408 (v = vs.105) .aspx) или например, с помощью [Изолирующий шпион] (http://isostorespy.codeplex.com/). – Romasz

+0

Он работал хорошо. Большое вам спасибо ^^ – Carson

Смежные вопросы