- Home /
Load TextAsset for serialization.
Hi
I use serialization to save & load scenes, the only problem is when I want to load the scene from a text asset, here's my current code for loading:
Stream stream = File.Open("Data.data", FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
Debug.Log ("Data");
data = (MyData)bformatter.Deserialize(stream);
stream.Close();
It works fine when I load from a file, but when I shall try to load it from a TextAsset it won't work, I have tried this code: loadFile is my TextAsset.
MemoryStream memStream = new MemoryStream();
memStream.Write(loadFile.bytes, 0, loadFile.bytes.Length);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
Debug.Log ("Reading Data");
data = (MyData)bformatter.Deserialize(memStream);
memStream.Close();[/code]
But then it gives my an error saying something like: "Failed reading end of file" or "Couldn't read to end of file".
Does someone know how to get it working?
[Update]
Thanks, although I can't get it to work: This is the error I'm getting now:
SerializationException: serializationStream supports seeking, but its length is 0
And this is the code I now use for loading:
MemoryStream memStream = new MemoryStream();
byte[] bytes = System.Convert.FromBase64String(loadFile.text);
memStream.Write(bytes, 0, bytes.Length);
... as usual
Do you know what I'm doing wrong?
As shown in code below, reading in binary data with FromBase64String works like a charm. Is the serialized data stream written/encoded correctly?
After looking into $$anonymous$$emoryStream documentation I think you're forgetting to reset the position back to 0:
memStream.Seek(0, SeekOrigin.Begin);
I found the reason it didn't work, a txt file with binary data wont show up as text in Unity, but I found another solution, I can save the data to a variable ins$$anonymous$$d.
Answer by Jaap Kreijkamp · Nov 28, 2009 at 02:26 AM
I don't know if this is te case, but can imagine textasset does mangle binary data as it is a text format. A possible simple solution would be using from package System.Convert
: Base64.ToBase64String
and Base64.FromBase64String
.
EDIT2: I think the reason your code doesn't work is because you forget to place the stream position back to the start after writing the data:
memStream.Seek(0, SeekOrigin.Begin);
EDIT: below sample code that can read in a Base64 encoded textasset into a byte[]
Example code:
using UnityEngine; using System.Collections;
public class JTestSerialization : MonoBehaviour {
public TextAsset binText;
// Use this for initialization
void Start () {
byte[] data = new byte[] { 0x12, 0x55, 0x33, 0x00, 0x01 };
if (binText == null) {
Debug.Log("" +System.Convert.ToBase64String(data));
return;
}
byte[] data2 = System.Convert.FromBase64String(binText.text);
if (data.Length != data2.Length) {
Debug.Log("Data length differs " + data.Length + " != " + data2.Length);
}
else {
int errors = 0;
for (int i = 0; i < data.Length; i++) {
if (data[i] != data2[i]) errors++;
}
if (errors > 0) Debug.Log("number of differences: " + errors);
else Debug.Log("data read in correctly!!!");
}
}
}
To use this example, create text asset with the following text:
ElUzAAE=
And link the text asset to the binText property of the GameObject with this script attached. If you don't link the textasset on debug the string that should be put into the text asset is shown. I have tested it with binary data with length of 10.000 bytes and it still works so should probably be good enough.
As you can see the only line that really matters is:
byte[] data2 = System.Convert.FromBase64String(binText.text);
The base64 encoding can of course be done with any base64 utility, or as shown in code with ToBase64String
.
This seems very plausible. All it would take is for one binary 0 to be written out to the file, for it to look like a premature end-of-file to many libraries that read text from a file.
Thanks, although I can't get it to work: This is the error I'm getting now: SerializationException: serializationStream supports seeking, but its length is 0
See above for an updated code.
Answer by Bampf · Dec 01, 2009 at 07:53 PM
I'm pretty sure you need to "rewind" the stream after writing out to it, in order for Deserialize to start reading from the beginning. Use
memStream.Seek(0, SeekOrigin.Begin);
If that isn't the problem, I suggest you use Debug.Log to print out loadFile.bytes.Length, as a sanity check. If it's zero, then let's have a look at the line(s) where you initialize your TextAsset.