2014-02-16 46 views

回答

5

下載文件是一個很大的課題,可以通過多種方式完成。我假設你知道你要下載的文件的Uri,並且想要你的意思是本地IsolatedStorage

我會舉三個例子說明如何完成(還有其他方法)。

1. simpliest例如將通過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.Resultstring - 這是該方法的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 Mb),則此方法可能會出現問題。

3.第三種方法 - 使用WebRequest再次與異步的await,但可以改變這個方法通過緩衝下載文件,因此不要使用太多內存:

首先我需要通過一種方法來延長我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

謝謝羅馬茲。保存此文件後,您能否向我顯示我的計算機中的IsolatedStorage文件夾的位置? – Carson

+2

@Carson IsolatedStorage文件夾位於您的手機中,這是與您的應用程序嚴格連接的「地點」,沒有其他應用程序可以訪問它。但是,您肯定可以通過[IsolatedStorage Explorer](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh286408(v = vs.105).aspx)或例如[IsolatedStorage Spy](http://isostorespy.codeplex.com/)。 – Romasz

+0

它運作良好。非常感謝你^^ – Carson

相關問題