3

我想将Pastebin (raw)中的文本下载到 texfile 中。我创建了一个IEnumerator,但不知何故它只是创建了一个空文本文件。

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

3 回答 3

4

WebClient 不是为在 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;
}

请务必通过调用来启动 DownloadTextFileStartCoroutine(DownloadTextFile())

于 2017-08-31T20:52:23.077 回答
3

Scott Chamberlain 的解决方案是在 Unity 中执行此操作的正确推荐WWW的方法,因为API 在后台处理线程问题。您只需使用协程下载它,然后使用File.WriteAllXXXScott 提到的功能之一手动保存它。

我添加了这个答案,因为这个问题是专门询问的,WebClient而且有时使用WebClient很好,比如大数据。

问题是你正在让步WebClient。您不必WebClient像以前那样在协程中屈服。只需订阅DownloadFileCompleted将在另一个线程上调用的事件。为了在该DownloadFileCompleted回调函数中使用 Unity 函数,您必须使用本文UnityThread中的脚本并在函数的帮助下执行 Unity函数。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;
    });
}
于 2017-09-01T01:10:20.983 回答
1

确保将 WebClient 放在 using 语句中,以便它可以正确处理并确保下载完成。对于 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) {  }
        }
于 2017-08-31T20:43:58.633 回答