0

In Unity3d Webgl I download and write big file (about 100 mb and more) to cache (indexeddb).

I downloaded file with UnityWebRequest and write file in downloadHandler. Sometimes after call filestream.Write() or filestream.Flush() Chrome will crash.

Exception not available, only crash tab of chrome. Crash happens abount in 50 percent of dowloads.

public class Downloader : MonoBehaviour
{
    public IEnumerator DownloadFileCoroutine(string url, string filePath,     string clientName, int fileId, Action<int> downloadedCallback)
    {
    var currentWebRequest = UnityWebRequest.Get(url);
    currentWebRequest.downloadHandler = new ToFileDownloadHandler(new byte[64 * 1024], filePath);

    var downloadHendler = (currentWebRequest.downloadHandler as ToFileDownloadHandler);
    currentWebRequest.Send();
    while (!currentWebRequest.isDone && !currentWebRequest.isNetworkError && !currentWebRequest.isHttpError)
    { 
        if (currentWebRequest.isNetworkError)
        {
            yield break;
        }
    }

    if (currentWebRequest.isNetworkError)
    {
        downloadHendler.Cancel();
    }
    else
    {
        /// suceess
    }
}

public class ToFileDownloadHandler : DownloadHandlerScript
{
    private int _expected = -1;
    private long _received = 0;
    private readonly string _filepath;
    private readonly FileStream _fileStream = null;
    private bool _canceled = false;

    public ToFileDownloadHandler(byte[] buffer, string filepath) : base(buffer)
    {
        CreateDir();
        _filepath = filepath;
        _fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write);
    }

    protected override byte[] GetData() { return null; }

    protected override bool ReceiveData(byte[] data, int dataLength)
    {
        if (data == null || data.Length < 1)
        {
            return false;
        }
        _received += dataLength;
        if (!_canceled)
        {
            _fileStream.Write(data, 0, dataLength);
            _fileStream.Flush();
        }
        return true;
    }

    protected override float GetProgress()
    {
        if (_expected < 0) return 0;
        return (float)_received / _expected;
    }

    protected override void CompleteContent()
    {
        _fileStream.Close();
        _isComplete = true;
    }

    protected override void ReceiveContentLength(int contentLength)
    {
        _expected = contentLength;
    }

    public void Cancel()
    {
        if (_canceled) return;
        _canceled = true;
        if (_fileStream != null)
        {
            _fileStream.Close();
        }
        File.Delete(_filepath);
    }

        private void CreateDir()
    {
        cachePath = Application.persistentDataPath;
        if (!Directory.Exists(cachePath))
        {
            Directory.CreateDirectory(cachePath);
        }
    }
}
}
Programmer
  • 121,791
  • 22
  • 236
  • 328
Knaus Irina
  • 789
  • 5
  • 15
  • 35
  • It's worth mentioning your Unity version. Also, why not try it on Firefox and also on a standard build and tell me if this problem is happen there too – Programmer Oct 27 '17 at 19:53
  • Unity version is 2017.1.p03. I develop for chrome browser and webgl. – Knaus Irina Oct 30 '17 at 05:41
  • Try this on Firefox and see if that issue is still there. I just want to know if this is Chrome specific issue – Programmer Oct 30 '17 at 05:47
  • In FireFox always get error: "out of memory" when write file with FileStream – Knaus Irina Oct 30 '17 at 06:33
  • At least we see an actual error now. Maybe this is WebGL bug on Unity. Try build for PC and Android and see what happens too. – Programmer Oct 30 '17 at 06:36
  • Its okey standalone. – Knaus Irina Oct 30 '17 at 07:07
  • Open the file with `FileMode.Append` instead of `FileMode.Create` and tell me what happens. Also, why not just store those downloaded bytes to an array, when download is done (`CompleteContent`) , save them instead of saving each time `ReceiveData` is called....This may actually fix your issue – Programmer Oct 30 '17 at 08:10
  • I open file with File.Append. It`s also crush. Sometimes crash became before write file after call ReceiveContentLength(int contentLength) (DownloadHandlerScript) – Knaus Irina Oct 30 '17 at 08:30
  • In webgl CompleteContent not called while not whole file dowloaded. – Knaus Irina Oct 30 '17 at 08:35
  • `CompleteContent` should be called when the data has finished downloading. If this is not the case then file for a bug report on both issue – Programmer Oct 30 '17 at 08:40
  • I try download all bytes to an array and then its write to file, but got error when read its data – Knaus Irina Oct 30 '17 at 10:47

0 Answers0