💬
UnityWebRequestの微妙さを改善する
Unityを使うならUnityWebRequestを使うってのが定石かと思うんですが、2つ気になる点があります。
- byte[]だと2GB以上のデータが入ってくるとデータ欠損するやないかい!
- awaitできへんのかい!
ということでStreamに直書きする拡張を作りました。
DownloadHandlerScriptには進捗管理の処理を省いてますが、必要なら簡単に記述できると思うんで調べてみてください(投げやり)
internal class StreamedDownloadHandler : DownloadHandlerScript
{
private readonly Stream _writeStream;
public StreamedDownloadHandler(Stream writeStream)
{
_writeStream = writeStream;
}
protected override bool ReceiveData(byte[] data, int dataLength)
{
_writeStream.Write(data, 0, dataLength);
return true;
}
protected override void CompleteContent()
{
_writeStream.Flush();
_writeStream.Seek(0, SeekOrigin.Begin);
}
}
public static class UnityWebRequestExtensions
{
public static async Task WriteToStreamAsync(this UnityWebRequest request, Stream stream)
{
var downloadHandler = new StreamedDownloadHandler(stream);
request.downloadHandler = downloadHandler;
request.SendWebRequest();
while (request.isDone == false)
{
// 毎フレーム確認マン
await Task.Delay(1);
}
}
}
使用はこう
public async Task SomeMethod()
{
using var fileStream = File.OpenWrite(Path.Combine(Application.dataPath, "test.txt"));
using var webRequest = new UnityWebRequest("http://www.google.com/");
await webRequest.WriteToStreamAsync(fileStream);
}
エラー処理とかはSomeMethodで行う想定。
必要ならCryptoStreamとか作れば暗号化しながらファイル保存したりできる。
UnityWebRequestそれ自体をStreamReaderにできそうな気もするけど考え中。
Discussion