c# webClient.DownloadFile 不下载,它只是创建一个空文本文件

c# webClient.DownloadFile doesn't download, it just creates an empty text file

我想从 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");
}

提前致谢。

确保将 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) {  }
        }

WebClient 并非设计为在 Unity3D 中使用,yield return version; 不等待文件下载。

您可以使用 WWW class 并以这种方式执行下载。 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())

来启动 DownloadTextFile

Scott Chamberlain 的 正确的 推荐的 WWW 以来在 Unity 中执行此操作的方法API 在后台处理线程问题。您只需要使用协同程序下载它,然后使用 File.WriteAllXXX 函数之一手动保存它,就像 Scott 提到的那样。

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

问题是你在屈服 WebClient。您不必像以前那样在协程中 yield WebClient 。只需订阅它的 DownloadFileCompleted 事件,该事件将在另一个线程上调用。为了在 DownloadFileCompleted 回调函数中使用 Unity 函数,您必须使用 this post 中的 UnityThread 脚本并在 [=20] 的帮助下执行 Unity 函数=] 函数..

这是一个完整的例子(需要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;
    });
}