Copy binary file from resources to PersistentDataPath
I have a database in "Assets/Resources/db.sqlite" and I want to copy this to the PersistentDataStorage if it doesn't already exist there (Windows, Android and IOS):
private const string DatabaseName = "db.sqlite";
private string FullPersistentDataBasePath { get { return Application.persistentDataPath + "/" + DatabaseName; } }
private bool HasDatabase()
{
bool result = File.Exists(FullPersistentDataBasePath);
Debug.Log("Has persistent database already: " + result);
return result;
}
// Copy from Assets/Resources ==> PersistentDataPath
private void CopyDatabase()
{
// ? How to do this for Windows, Android and IOS? TextAsset? BinaryFormatter? How?
// var db = Resources.Load(DatabaseName);
}
I use the latest stable Unity (version 2019.3.11f1).
Final solution:
using DataBank; // My namespace that contains my SQLiteHelper
using System.IO;
using UnityEngine;
public class CopyDatabase : MonoBehaviour
{
public TextAsset DatabaseInResource = null;
private void Awake()
{
GotoScene.CanGotoNextScene = false;
if (!HasUp2DateDatabase())
{
Copy();
}
GotoScene.CanGotoNextScene = true;
}
private bool HasUp2DateDatabase()
{
// TODO: check database version also.
return File.Exists(SqliteHelper.FullPersistentDatabasePath);
}
private void Copy()
{
if (DatabaseInResource == null)
{
throw new System.NullReferenceException("DatabaseInResource is null.");
}
byte[] data = DatabaseInResource.bytes;
File.WriteAllBytes(SqliteHelper.FullPersistentDatabasePath, data);
}
}
Answer by Bunny83 · May 08, 2020 at 02:08 AM
Well, first of all you should check the TextAsset manual page. There you can see that supported file extensions do not include the "sqlite" extension. So in order to actually load a binary file from the resources folder you would need to rename it and use the .bytes
extension.
Next thing in the Resources.Load method you have to omit the file extension so you have to use just the file name without the ".bytes". To actually get access to the bytes you just use the .bytes property of the TextAsset. Something like this:
var db = Resources.Load<TextAsset>("db");
byte[] data = db.bytes;
In order to write the file to the persistent data path you just use the ordinary System.IO.File methods.
System.IO.File.WriteAllBytes(yourFileName, data);
Note that it's generally better to use System.IO.Path.Combine() whenever you combine path fragments into one file path. It takes care about using the right slashes.
System.IO.Path.Combine(Application.persistentDataPath, DatabaseName);
Instead of using the assetdatabase and the resources folder / TextAssets you can also use the StreamingAssets folder. Though reading from that folder on android requires you to use the UnityWebRequest class since the streaming assets are actually included inside the APK zip file and there's no direct native access to those files.
Oh, I thought TextAsset was only for raw text. The file got copied but was empty so I made this property and then it worked: public TextAsset DatabaseInResource = null;
Thanks! Also thanks for the Path.Combine() tip!
Your answer
Follow this Question
Related Questions
Fast Distance Checking for many objects? (RTS Game) 0 Answers
Change SVGasset VectorGraphic at Runtime 1 Answer
Instantiate screenshots from camera *Realtime* 0 Answers
How to do something similar to AssetDatabase.Refresh during build? 0 Answers
How to change Image sources through the Resources folder 1 Answer