2017-08-31 4 views
3

Ich wollte einen Text von Pastebin (roh) in eine Texdatei herunterladen. Ich habe eine IEnumerator erstellt, aber irgendwie erstellt es nur eine leere Textdatei.C# webClient.DownloadFile wird nicht heruntergeladen, es erstellt nur eine leere Textdatei

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

Vielen Dank im Voraus.

Antwort

4

WebClient nicht verwendet werden, entworfen von innen Unity3D so, yield return version; wartet nicht auf die Datei heruntergeladen werden.

Was Sie tun könnten, ist die Klasse zu verwenden und den Download auf diese Weise durchzuführen. WWW ist Teil von Unity und wurde entwickelt, um mit der Funktionsweise von Unity zu arbeiten.

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; 
} 

unbedingt die DownloadTextFile starten, indem StartCoroutine(DownloadTextFile())

+0

Vielen Dank für diese schnelle und sehr hilfreiche Antwort. Es hat sehr gut funktioniert. – Chloe

+0

Gibt es eine Möglichkeit, den Download-Fortschritt zu sehen? – Chloe

+0

Ja, wenn Sie sich die Dokumentation von WWW ansehen, sehen Sie das Feld ['progress'] (https://docs.unity3d.com/ScriptReference/WWW-progress.html). lies das, um zu sehen, wie weit der Fortschritt ist. –

1

Stellen Sie sicher, dass Sie Ihren WebClient in eine using-Anweisung einfügen, damit der Download ordnungsgemäß abgeschlossen und sichergestellt werden kann. Für die Async-Version müssen Sie sicherstellen, dass Sie während der Arbeit nicht bailen.

 //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

Hinweis, das ist Unity3d so 'while (version.IsBusy) {}' ist ein großes Nein-Nein und wird das Spiel sperren. Sie sollten 'while (version.IsBusy) {yield return 0; } 'Stattdessen wartet es auf einen Frame und prüft erneut, ob es besetzt ist. –

+0

Guter Anruf Scott. Ich ignoriere den Unity-Teil vollständig. Dein Beitrag ist genau richtig. –

3

Scott Chamberlain solution das ist die richtigen und die empfohlen Weg, dies in Unity Aufruf zu tun, da WWW API Threadingprobleme im Hintergrund verarbeitet. Sie müssen nur Coroutine verwenden, um es herunterzuladen, dann speichern Sie es mit manuell mit einer der File.WriteAllXXX Funktionen wie Scott erwähnt.

Ich füge diese Antwort hinzu, da die Frage speziell nach WebClient fragt und es gibt Zeiten, in denen WebClient in Ordnung ist, wie große Daten.

Das Problem ist, dass Sie WebClient geben. Sie müssen nicht WebClient in einer Coroutine ergeben, wie Sie getan haben. Abonnieren Sie einfach das DownloadFileCompleted Event, das auf einem anderen Thread aufgerufen wird. Um Unity-Funktion in dieser DownloadFileCompleted Callback-Funktion zu nutzen, müssen Sie UnityThread Skript von this Post verwenden und die Unity-Funktion mit Hilfe der UnityThread.executeInUpdate Funktion ausführen ..

Hier ist ein komplettes Beispiel (UnityThread ist erforderlich):

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; 
    }); 
} 
Verwandte Themen