Downloading an Object from AWS S3 to a Unity Application
In this short article I will go over how to grab an object from an S3 bucket and load it into a class instance used by a Unity Project. This is a continuation of earlier articles on interacting with S3 from Unity.
Detailed information about this topic can be found at the AWS documentation here:
Amazon Simple Storage Service (S3) — AWS Mobile SDK for Unity
I’m downloading a data file which contains the data for an instance of the following class:
The code to download an object for this class is below. It is a little more complicated than the basic AWS example in the S3 docs, which merely downloads a text file. Our class above is more complex and contains image data as well as text:
Let’s go over this part by part. First we call the Get Object Async method of the S3 Client which will receive the bucket name, file name, and a response lambda as parameters:
Next, in the lambda, we check the response and if it is not null then we begin processing the object to eventually de-serialize it to an instance of the above class.
Above we declare a byte array and open a stream reader using the response stream we got back from S3.
Next, we open a memory stream to store the data from the stream reader. We then read the data from the stream reader and write it to the memory stream.
The above code is a little complex so it requires a little more explanation.
First we declare a buffer and bytes read. The buffer is a byte array. The size is basically how many bytes we want to read at a time. This can be variable depending on your data. Bytes read is basically an int set to the default value for ints (0).
In the while loop, we read the data from the stream and write it to our buffer. The reader.BaseStream.Read method takes as parameters the buffer we want to store the data to, an offset in the stream (here 0 — no offset), and the length of our buffer. This method will return the number of bytes read. Here it will be max of 512 each read.
After we read from the stream, we write the data to our memory stream with:
We then repeat the while loop, reading data 512 bytes at a time until there is no data left in the stream reader (basically when bytes read = 0). We then set our data byte array (declared higher up above) to the memory stream we just read data into:
Next we de-serialize the data into an instance of our class:
Above we create a new memory stream with our data array. We then declare a binary formatter and an instance of our Case class (here called downloaded case). Basically we are going to de-serialize binary data that is stored in the memory streat. As the data we read from S3 was originally serialized and uploaded using a binary formatter, it should de-serialize back to the instance without any issues. This is assuming the data was not corrupted or changed after uploaded to S3.
After we de-serialize then we are able to use the new Case instance as we see fit in the application.
This example was a little more complicated as the data we originally stored in S3 is more complex than a simple text file. Here we uploaded a mix of data including strings and a byte array representing an image and then downloaded it.
The method/steps you use to process and de-serialize your data may differ depending on what you save to S3. The main method for interacting with S3 thought is S3Client.GetObjectAsynch().