- Home /
Not able to load binary file through Resources.Load
Hi I have a binary file which will be loaded during runtime.
But I'm not able to load it during runtime through Resources.Load
Here's my codes: // this is how I save file in editor var b = new BinaryFormatter(); var f = File.Create(path); b.Serialize(f, dataList); f.Close();
// this is how I load file in editor
var b = new BinaryFormatter();
var f = File.Open(path, FileMode.Open);
dataList = (List<PuzzleEditorData>)b.Deserialize(f);
f.Close();
// both save and load in editor is working fine
// I have make sure my file is saved under Assets/Resources folder and the file name is call leveldata.bytes
// this is how I load the file during runtime
TextAsset asset = Resources.Load("leveldata") as TextAsset;
MemoryStream s = new MemoryStream(asset.bytes); // !This is where it crashes and say NullReferenceException but I did verified that asset is not null
var b = new BinaryFormatter();
dataList = (List<PuzzleEditorData>)b.Deserialize(s);
Answer by LovesSolvingProblems · Jan 20, 2015 at 09:06 AM
I've been struggling with this as well. Mike Gieg's live training on persistence was awesome but I'd sure like to see the right way to do this... And save it to an online database. There's got to be a cleaner way but this at least gets the job done.
Create a folder right under Assets named, "StreamingAssets".
Drag your binaries to that folder and they will be included in the apk, but in a zipped unusable format.
In the following load method it checks to see if the file has been unpacked. If not, it unpacks it to the persistentDataPath. Either way it deserializes from there.
Hope this helps and hope someone can show us a better way.
public void Load(string fileName){ //example: fileName="Level_100.dat"
//Check if file needs to be unpacked
if (!File.Exists (Application.persistentDataPath + "/" + fileName)) UnpackMobileFile(fileName);
//check again in case it didn't work
if ( File.Exists (Application.persistentDataPath + "/" + fileName)){
//Load data from file to loader
BinaryFormatter bf = new BinaryFormatter();//engine that will interface with file
FileStream file = File.Open (Application.persistentDataPath + "/" + fileName,FileMode.Open);
LevelData loader = (LevelData)bf.Deserialize(file); //restore instance of below class as sample save
file.Close();
loader.PopulateGameFromLoader(); //move data from loader to game objects
Debug.Log ("Loaded " + Application.persistentDataPath+ fileName );
}
}
void UnpackMobileFile (string fileName){ //copies and unpacks file from apk to persistentDataPath where it can be accessed
string destinationPath = System.IO.Path.Combine (Application.persistentDataPath, fileName);
string sourcePath = System.IO.Path.Combine (Application.streamingAssetsPath, fileName);
//if DB does not exist in persistent data folder (folder "Documents" on iOS) or source DB is newer then copy it
if (!System.IO.File.Exists (destinationPath) || (System.IO.File.GetLastWriteTimeUtc(sourcePath) > System.IO.File.GetLastWriteTimeUtc(destinationPath))) {
if (sourcePath.Contains ("://")) {// Android
WWW www = new WWW (sourcePath);
while (!www.isDone) {;} // Wait for download to complete - not pretty at all but easy hack for now
if (String.IsNullOrEmpty(www.error)) {
System.IO.File.WriteAllBytes(destinationPath, www.bytes);
} else {
Debug.Log ("ERROR: the file DB named " + fileName + " doesn't exist in the StreamingAssets Folder, please copy it there.");
}
} else { // Mac, Windows, Iphone
//validate the existens of the DB in the original folder (folder "streamingAssets")
if (System.IO.File.Exists (sourcePath)) {
//copy file - alle systems except Android
System.IO.File.Copy (sourcePath, destinationPath, true);
} else {
Debug.Log ("ERROR: the file DB named " + fileName + " doesn't exist in the StreamingAssets Folder, please copy it there.");
}
}
}
}
This was beyond useful, thank you! This kind of functionality should be within the UNITY framework.
I don't understand why you need to copy the file from Strea$$anonymous$$gAssets to PersistentDataPath. Why not just load the bin directly from Strea$$anonymous$$gAssets?
if (File.Exists(Application.strea$$anonymous$$gAssetsPath + "/" + fileName))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.strea$$anonymous$$gAssetsPath + "/" + fileName, File$$anonymous$$ode.Open);
YourData data = (YourData)bf.Deserialize(file);
file.Close();
}
Because the point is to read and write the file. Your code does not work on android because the strea$$anonymous$$g assets are packed inside the APK and therefore are read-only. You can not use System.IO methods to read strea$$anonymous$$g assets on android or WebGL. You have to use a WebRequest or the old WWW class.