Hello Folks,
i’m currently working on an unity based iOS project. so far i’ve overcome many problems (event handling for overlapping buttons, overlapping scrollviews, etc. etc.) … Now there’s another nice problem to be solved:
i’m doing a sync between offline SQlite and online mySQL database (working nicely), as well as downloading many, many files. some of them are videos with big file sizes, for example. those files are too big to be kept in memory completely. so even when i’m happily calling WWW.dispose after completing a filedownload (and the memory consumption is going down again, at least according to System.GC.GetTotalMemory(false), … there is obviously always a point where i’m running into “out of memory” error because the file to be downloaded is bigger than the available memory.
How would you guys implement a file download which is opening a connection, downloading a few kilobytes (and immediately append to the downloaded file, until it’s completed). I was checking out some c# stream based download functions, some of them were using System.Uri which was not available in unity (for both subset and full 2.0 player settings) …
Any advice ?
// Based on this:
// Downloading file via TcpClient from HTTP server - Stack Overflow
public class main : MonoBehaviour
{
string host = "www.server.com";
string uri = "/path/to/file/1920x1080.mp4";
uint contentLength;
int n = 0;
int read = 0;
NetworkStream networkStream;
FileStream fileStream;
Socket client;
// Use this for initialization
void Start ()
{
string query = "GET " + uri.Replace(" ", "%20") + " HTTP/1.1
" +
"Host: " + host + "
" +
"User-Agent: undefined
" +
"Connection: close
"+
"
";
Debug.Log (query);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
client.Connect(host, 80);
networkStream = new NetworkStream(client);
var bytes = Encoding.Default.GetBytes(query);
networkStream.Write(bytes, 0, bytes.Length);
var bReader = new BinaryReader(networkStream, Encoding.Default);
string response = "";
string line;
char c;
do
{
line = "";
c = '\u0000';
while (true)
{
c = bReader.ReadChar();
if (c == '\r')
break;
line += c;
}
c = bReader.ReadChar();
response += line + "
";
}
while (line.Length > 0);
Debug.Log ( response );
Regex reContentLength = new Regex(@"(?<=Content-Length:\s)\d+", RegexOptions.IgnoreCase);
contentLength = uint.Parse(reContentLength.Match(response).Value);
fileStream = new FileStream( Application.persistentDataPath + "/download.mp4", FileMode.Create);
}
void Update()
{
byte[] buffer = new byte[4 * 1024];
if (n < contentLength)
{
if (networkStream.DataAvailable)
{
read = networkStream.Read(buffer, 0, buffer.Length);
n += read;
fileStream.Write(buffer, 0, read);
}
Debug.Log ( "Downloaded: " + n + " of " + contentLength + " bytes ..." );
}
else
{
fileStream.Flush();
fileStream.Close();
client.Close();
}
}
}
Another alternative: Systme.Net.WebClient
If you can explain me how to make this snippet compatible with ipv6, you are a life saver