Downloaded file corrupted

I am working on a launcher that would allow the user to download only the files they want from my google drive. Problem I am having is that the files download really fast and are corrupted. The files are mostly zip files but I do have some that are exe files.
Can anyone see why it is corrupting the files? Here is the current code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System;

public class Launcher : MonoBehaviour
{
    public Text text2;
    public Slider progressBar;
    public Button FPSC;
    public GameObject fpscPanel;
    public GameObject bar;
    public void FpsCclassic()
    {
        bar.SetActive(true);
        string url = "https://drive.google.com/uc?export=download&id=16LR32k5nLZuyO-cyQWHMfU55Uhjy1Mqi";
        StartCoroutine(Get(url));
     
        var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string fileName = desktop + "\\FPSC Setup.exe";
        WebClient webClient = new WebClient();
        webClient.DownloadFile(new Uri(url), fileName);
    }

    private IEnumerator Get(string url)
    {
        using(UnityWebRequest ur = UnityWebRequest.Get(url))
        {
            yield return ur.SendWebRequest();
            if(ur.isNetworkError || ur.isHttpError)
            {
                Debug.Log("Error: " + ur.error);
                text2.text = "Error: " + ur.error;
            }
            else
            {
                progressBar.value = ur.downloadProgress;
                Debug.Log("Received: " + ur.downloadHandler.text);
                text2.text = ur.downloadHandler.text;
            }
        }
    }
    public void OpenPanel()
    {
        if(FPSC)
        {
            fpscPanel.SetActive(true);
        }
    }

    public void EndProgram()
    {
        Application.Quit();
    }
}

I don’t have direct experience with either UnityWebRequest or WebClient, but it seems exceedingly unlikely that you want to be invoking both of them at once in a way that neither references the other. What’s your reasoning there?

In terms of general debugging, if you try to download something in your program and don’t get the data you were expecting, the first thing to test is usually to put the same URI into a web browser and see what happens there.

I have both there for debugging, but it seems that I was in the middle of trying something without commenting out parts of the code.

In general, yes, but the link is good.

My problem is, after some sleep, I noticed that the file isn’t really corrupt, just incomplete. By downloading the file via browser, the file size is 348mb. Downloading via code, the file size is 39kb. That’s great if it is a picture or text, but not a whole file.

I have tried using zip files and even a single 3d model, but they all end in the same partial file of only 39kb. Is there a way to writeallbytes to a folder?

Ok, so, I have rewritten the code from scratch. In visual studio this works perfectly, but not in unity. Can anyone explain why or what is only allowing 40kb download??

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System;
using System.ComponentModel;

public class Launcher : MonoBehaviour
{
    public Text text2;
    public Slider progressBar;
    public Button FPSC;
    public GameObject fpscPanel;
    public GameObject bar;
    public void FpsCclassic()
    {
        bar.SetActive(true);
        string url = "https://drive.google.com/uc?export=download&id=16LR32k5nLZuyO-cyQWHMfU55Uhjy1Mqi";
        var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string fileName = desktop + @"\\FPSC Setup.exe";
        WebClient webClient = new WebClient();
        webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
        webClient.DownloadFileAsync(new Uri(url), fileName);


    }
    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar.value = e.ProgressPercentage;
        double bytesIn = double.Parse(e.BytesReceived.ToString());
        double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
        double percentage = bytesIn / totalBytes * 100;
        text2.text = "Downloading!";
    }

    private void Completed(object sender, AsyncCompletedEventArgs e)
    {
        progressBar.value = 0;
        text2.text = "Downloaded!!!";

    }
    public void OpenPanel()
    {
        if(FPSC)
        {
            fpscPanel.SetActive(true);
        }
    }

}

I did some poking around and it seems that since 2018 update, unitywebrequest and webclient are broken for large files over 40kb. I am guessing I will have to find a new route for what I need. Just sucks, because you learn something new and you cannot use it for anything other than highscores and textures.

heres the script for downloading files

public IEnumerator DL()
    {
  
            //Download
            UnityWebRequest dlreq = new UnityWebRequest(downloadlink);
            dlreq.downloadHandler = new DownloadHandlerFile(filepath);
            UnityWebRequestAsyncOperation op = dlreq.SendWebRequest();
            while (!op.isDone)
            {
                 //here you can see download progress
                Debug.Log(dlreq.downloadedBytes / 1000 + "KB");
            yield return null;
            }
            if (dlreq.isNetworkError || dlreq.isHttpError)
            {
                Debug.Log(dlreq.error);
            }
            else
            {
                Debug.Log("download success");
            }
            dlreq.Dispose();
            yield return null;
        }
    }

Tried and the bytes went from 39kb to 3kb. I think if have found a way to make this work by using Application.OpenUrl();
It seems to work by sending straight to the page. Not really what I was going for, but I will settle for it. I will have to test with my forum friends and see if it meets their needs. If it doesn’t, then I will just have to make in visual studio.

You might be asking, What is the end goal? Well, the end goal is to make a launcher in which people can download model packs and programs straight from my site without actually using my website. Some people on the forums stated that because my website is through weebly they are not able to access it.

So my thought was to make a launcher that gives access without having to actually use the site, but only the file sharing. Then my next question was if they could download the files from google drive and that was a yes.

I use unity for just about everything I do now, but learning this new feature sparked more creative ideas. Thank you!

you are actually correct, I tried with larger files and it didn’t work. From my testing the largest I could download was 23mb, and 29mb and above failed, so the limit is between 23 and 29mb

dont know if its possible in your case but if you can split the file into 23mb parts you could use this method

Thank you for your help, but I have found that Application.OpenUrl() is working for me. Still not the desired effect, but it is working.

What do you mean by file corrupted?
UnityWebRequest certainly can download large files. Granted, for very large files you want to use DownloadHandlerFile, rather than default DownloadHandlerBuffer.
Since you mention Google Drive, check whether you are not downloading a Google Drive web page instead of the file.

2 Likes

can you confirm it with this script?

    public IEnumerator DL()
        {
  
                //Download
                UnityWebRequest dlreq = new UnityWebRequest(downloadlink);
                dlreq.downloadHandler = new DownloadHandlerFile(filepath);
                UnityWebRequestAsyncOperation op = dlreq.SendWebRequest();
                while (!op.isDone)
                {
                     //here you can see download progress
                    Debug.Log(dlreq.downloadedBytes / 1000 + "KB");
                yield return null;
                }
                if (dlreq.isNetworkError || dlreq.isHttpError)
                {
                    Debug.Log(dlreq.error);
                }
                else
                {
                    Debug.Log("download success");
                }
                dlreq.Dispose();
                yield return null;
            }
        }

It doesn’t download anything larger than 23 megabytes.

On files above 30mb it ticks twice on

 while (!op.isDone){

and declares download success, creating a 4kb file

All files tested uploaded to google drive and parsed with google drive link creator :

https://sites.google.com/site/gdocs2direct/

On unity version 2019.2

Try printing all HTTP response headers from UnityWebRequest.

1 Like

can you edit my script to show me how I do that please?

I wonder if this is possibly caused by this prompt on google drive…

Google Drive can't scan this file for viruses.

asdads.zip (448M) is too large for Google to scan for viruses. Would you still like to download this file?

maybe it is preventing the direct linking?

EDIT : tried with other direct links, its indeed the problem, the error is due to this google drive prompt that complains about not being able to check for viruses.

Thanks for your reply @Aurimas-Cernius

That might be the problem. Is it possible to bypass that error?

I think not, you will need to use another site to host your files instead of google drive

There may be an argument you can supply in the request that tells google not to try to do the virus check at all. I’m sure it’s possible to download arbitrary sized files from a place like Google!

Found a solution How To Download A Large File From Google Drive Using WGET Or CURL - Definitive Guide - Js Owl

Just add “&confirm=t” in the end of the link