2017-08-31 97 views
3

我想從Pastebin(raw)下載一個文本到一個texfile中。 我創建了一個IEnumerator,但不知何故,它只是創建一個空的文本文件。c#webClient.DownloadFile不下載,它只是創建一個空文本文件

public IEnumerator DownloadTextFile() 
{ 
    WebClient version = new WebClient(); 
    yield return version; 
    version.DownloadFileAsync(new Uri(myLink), "version.txt"); 
} 

public IEnumerator DownloadTextFile() 
{ 
    WebClient version = new WebClient(); 
    yield return version; 
    version.DownloadFile(myLink , "version.txt"); 
} 

在此先感謝。

回答

4

Web客戶端不設計爲從內Unity3D那樣使用,yield return version;不會等待要下載的文件。

你可以做的是使用WWW類,並執行下載的方式。 WWW是Unity的一部分,旨在以Unity的方式工作。

public IEnumerator DownloadTextFile() 
{ 
    WWW version = new WWW(myLink); 
    yield return version; 
    File.WriteAllBytes("version.txt", version.bytes); 

    //Or if you just wanted the text in your game instead of a file 
    someTextObject.text = version.text; 
} 

務必致電StartCoroutine(DownloadTextFile())

+0

謝謝你這個快速和非常有用的答覆。它工作得很好。 – Chloe

+0

有沒有辦法看到下載進度? – Chloe

+0

是的,如果您查看WWW的文檔,您將看到['progress'](https://docs.unity3d.com/ScriptReference/WWW-progress.html)字段。閱讀,看看進展有多遠。 –

1

確保您將WebClient放在使用語句中,以便它可以正確處置並確保下載完成。對於Async版本,您需要確保在忙時不要保釋。

 //Method 1 
     using (var version = new WebClient()) 
      version.DownloadFile("https://pastebin.com/raw/c1GrSCKR", @"c:\temp\version.txt"); 

     // Method 2 (better if you are working within Task based async system) 
     //using (var version = new WebClient()) 
     // await version.DownloadFileTaskAsync("https://pastebin.com/raw/c1GrSCKR", @"c:\temp\version.txt"); 

     // Method 3 - you can't dispose till is completed/you can also register to get notified when download is done. 
     using (var version = new WebClient()) 
     { 
      //version.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => 
      //{ 

      //}; 
      version.DownloadFileAsync(new Uri("https://pastebin.com/raw/c1GrSCKR"), @"c:\temp\version.txt"); 

      while (version.IsBusy) { } 
     } 
+1

請注意,這是Unity3d所以'while(version.IsBusy){}'是一個很大的禁忌,會鎖定遊戲。你應該做'while(version.IsBusy){yield return 0; },而是等待一幀,然後再檢查它是否忙。 –

+0

好電話斯科特。我完全忽略了Unity部分。你的帖子是現貨。 –

3

斯科特·張伯倫的solution啓動DownloadTextFile是適當建議辦法做到這一點在Unity因爲WWW API在後臺處理線程問題。您只需使用協同程序下載它,然後使用像Scott提到的File.WriteAllXXX函數之一手動保存它。

我添加了這個答案,因爲問題是特別詢問WebClient,有時候使用WebClient很好,比如大數據。

問題是您正在產生WebClient。您不必像您那樣在協同程序中產生WebClient。只需訂閱將在另一個主題上調用的DownloadFileCompleted事件即可。爲了使用統一的功能在DownloadFileCompleted回調函數,你必須使用UnityThread腳本this崗位,並與UnityThread.executeInUpdate功能的幫助下完成統一功能..

下面是一個完整的例子(需要UnityThread):

public Text text; 
int fileID = 0; 

void Awake() 
{ 
    UnityThread.initUnityThread(); 
} 

void Start() 
{ 
    string url = "http://www.sample-videos.com/text/Sample-text-file-10kb.txt"; 
    string savePath = Path.Combine(Application.dataPath, "file.txt"); 

    downloadFile(url, savePath); 
} 

void downloadFile(string fileUrl, string savePath) 
{ 
    WebClient webClient = new WebClient(); 
    webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DoSomethingOnFinish); 
    webClient.QueryString.Add("fileName", fileID.ToString()); 
    Uri uri = new Uri(fileUrl); 
    webClient.DownloadFileAsync(uri, savePath); 
    fileID++; 
} 

//THIS FUNCTION IS CALLED IN ANOTHER THREAD BY WebClient when download is complete 
void DoSomethingOnFinish(object sender, AsyncCompletedEventArgs e) 
{ 
    string myFileNameID = ((System.Net.WebClient)(sender)).QueryString["fileName"]; 
    Debug.Log("Done downloading file: " + myFileNameID); 

    //Ssafety use Unity's API in another Thread with the help of UnityThread 
    UnityThread.executeInUpdate(() => 
    { 
     text.text = "Done downloading file: " + myFileNameID; 
    }); 
} 
相關問題