gpt4 book ai didi

c# - 下载大文件

转载 作者:太空狗 更新时间:2023-10-29 22:29:43 26 4
gpt4 key购买 nike

通过下载带有 UnityEngine.WWW 的文件,我得到了错误

OverflowException: Number overflow.

我发现错误是由结构本身引起的,因为字节数组的字节数超过了 int.MaxValue 可以分配的字节数 (~2GB)。

返回带有www.bytes 的数组会引发错误,这意味着框架可能以其他方式存储数组。

我如何才能以其他方式访问下载的数据,或者是否有更大文件的替代方法?

public IEnumerator downloadFile()
{
WWW www = new WWW(filesource);

while(!www.isDone)
{
progress = www.progress;
yield return null;
}

if(string.IsNullOrEmpty(www.error))
{
data = www.bytes; // <- Errormessage fired here
}
}

最佳答案

新答案(Unity 2017.2 及以上版本)

使用UnityWebRequestDownloadHandlerFile . DownloadHandlerFile 类是新类,用于直接下载和保存文件,同时防止高内存使用。

IEnumerator Start()
{
string url = "http://dl3.webmfiles.org/big-buck-bunny_trailer.webm";

string vidSavePath = Path.Combine(Application.persistentDataPath, "Videos");
vidSavePath = Path.Combine(vidSavePath, "MyVideo.webm");

//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(vidSavePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(vidSavePath));
}

var uwr = new UnityWebRequest(url);
uwr.method = UnityWebRequest.kHttpVerbGET;
var dh = new DownloadHandlerFile(vidSavePath);
dh.removeFileOnAbort = true;
uwr.downloadHandler = dh;
yield return uwr.SendWebRequest();

if (uwr.isNetworkError || uwr.isHttpError)
Debug.Log(uwr.error);
else
Debug.Log("Download saved to: " + vidSavePath.Replace("/", "\\") + "\r\n" + uwr.error);
}

旧答案(Unity 2017.1 及以下版本)如果要在文件下载时访问每个字节,请使用)

像这样的问题就是为什么Unity的UnityWebRequest已创建,但它不会直接工作,因为 WWW API 现在在最新版本的 Unity 中的 UnityWebRequest API 之上实现,这意味着如果您遇到错误WWW API,您也可能会在使用 UnityWebRequest 时遇到同样的错误。即使它能正常工作,您也可能在 Android 等配备小内存的移动设备上遇到问题。

要做的是使用 UnityWebRequest 的 DownloadHandlerScript允许您分块下载数据的功能。通过分块下载数据,可以防止导致溢出错误。 WWW API 没有实现此功能,因此必须使用 UnityWebRequestDownloadHandlerScript 来分块下载数据。您可以阅读这是如何工作的 here .

虽然这应该可以解决您当前的问题,但您在尝试使用 File.WriteAllBytes 保存大量数据时可能会遇到另一个内存问题。使用 FileStream 做保存部分,只有在下载完成后才关闭它。

创建一个自定义 UnityWebRequest 以按如下方式分块下载数据:

using System;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class CustomWebRequest : DownloadHandlerScript
{
// Standard scripted download handler - will allocate memory on each ReceiveData callback
public CustomWebRequest()
: base()
{
}

// Pre-allocated scripted download handler
// Will reuse the supplied byte array to deliver data.
// Eliminates memory allocation.
public CustomWebRequest(byte[] buffer)
: base(buffer)
{

Init();
}

// Required by DownloadHandler base class. Called when you address the 'bytes' property.
protected override byte[] GetData() { return null; }

// Called once per frame when data has been received from the network.
protected override bool ReceiveData(byte[] byteFromServer, int dataLength)
{
if (byteFromServer == null || byteFromServer.Length < 1)
{
Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer");
return false;
}

//Write the current data chunk to file
AppendFile(byteFromServer, dataLength);

return true;
}

//Where to save the video file
string vidSavePath;
//The FileStream to save the file
FileStream fileStream = null;
//Used to determine if there was an error while opening or saving the file
bool success;

void Init()
{
vidSavePath = Path.Combine(Application.persistentDataPath, "Videos");
vidSavePath = Path.Combine(vidSavePath, "MyVideo.webm");


//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(vidSavePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(vidSavePath));
}


try
{
//Open the current file to write to
fileStream = new FileStream(vidSavePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
Debug.Log("File Successfully opened at" + vidSavePath.Replace("/", "\\"));
success = true;
}
catch (Exception e)
{
success = false;
Debug.LogError("Failed to Open File at Dir: " + vidSavePath.Replace("/", "\\") + "\r\n" + e.Message);
}
}

void AppendFile(byte[] buffer, int length)
{
if (success)
{
try
{
//Write the current data to the file
fileStream.Write(buffer, 0, length);
Debug.Log("Written data chunk to: " + vidSavePath.Replace("/", "\\"));
}
catch (Exception e)
{
success = false;
}
}
}

// Called when all data has been received from the server and delivered via ReceiveData
protected override void CompleteContent()
{
if (success)
Debug.Log("Done! Saved File to: " + vidSavePath.Replace("/", "\\"));
else
Debug.LogError("Failed to Save File to: " + vidSavePath.Replace("/", "\\"));

//Close filestream
fileStream.Close();
}

// Called when a Content-Length header is received from the server.
protected override void ReceiveContentLength(int contentLength)
{
//Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength));
}
}

使用方法:

UnityWebRequest webRequest;
//Pre-allocate memory so that this is not done each time data is received
byte[] bytes = new byte[2000];

IEnumerator Start()
{
string url = "http://dl3.webmfiles.org/big-buck-bunny_trailer.webm";
webRequest = new UnityWebRequest(url);
webRequest.downloadHandler = new CustomWebRequest(bytes);
webRequest.SendWebRequest();
yield return webRequest;
}

关于c# - 下载大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50689859/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com