Best way to save large amount of data locally in unity3D android? [closed]

NOTE - do not use "StreamWriter" for any reason.

Just use the trivial File.Write commands.

This is a common misunderstanding in Unity!

Regarding this topic, a bad example code was propagated on the www for years. Simply use File.Write.


Regarding the question on this page, "thousands" of entries is absolutely nothing.

Note that for example: any tiny icon image in your app will completely dwarf the size of your name/address data!

(1) extremely easy to save a text file:

// IO crib sheet..
// filePath = Application.persistentDataPath+"/"+fileName;
// check if file exists System.IO.File.Exists(f)
// write to file File.WriteAllText(f,t)
// delete the file if needed File.Delete(f)
// read from a file File.ReadAllText(f)

that's all there is to it.

   string currentText = File.ReadAllText(filePath);

NOTE WELL...........

// filePath = Application.persistentDataPath+"/"+fileName;
// YOU MUST USE "Application.persistentDataPath"
// YOU CANNOT USE ANYTHING ELSE/
// NOTHING OTHER THAN "Application.persistentDataPath" WORKS/
// ALL OTHER OPTIONS FAIL ON ALL PLATFORMS/
// YOU CAN >ONLY< USE Application.persistentDataPath IN UNITY.

Store the info any way you want, probably JSON or csv.

It is dead easy to use Json in Unity, there are 100s of examples on stackoverflow.

example https://stackoverflow.com/a/38535392/294884

(2) once you have say one million items. you can learn about using the local SQL database, which is well worth learning. Do what Łukasz Motyczka says in the comments.

(3) Never use PlayerPrefs - it is much harder and messy!


For anyone else that comes here because they're trying to access Application.StreamingDataPath (or anything else within an APK for that matter) you cannot simply use the File api as discussed in Fattie's response. You need to use a web request as the APK is essentially a compressed folder and System.IO cannot access the internals of these packages.

You will need to use UnityWebRequest to GET the data from the desired location within the PKG. You can include raw files in your game by adding a folder anywhere in the project and calling it StreamingAssets (Resource folders are reconstructed inside the APK and can't be directly accessed, they're also loaded into memory at runtime which makes the game start very slowly), then point your UWR at Application.streamingDataPath and get the data from request.downloadHandler.data.

For saving new data, you have to use Application.persistantDataPath, at which point using System.IO.File is just fine.

Here is an example of grabbing data out of the APK!/assets/ folder (where android puts the StreamingAssets folder) and then saving it to a location for later use.

public IEnumerator GetSomeDataAndThenSave(string path)
{
    UnityWebRequest request = UnityWebRequest.Get(path);

    request.Send();

    while(!request.isDone)
    {
        yield return null;
    }

    if (!request.isNetworkError && (request.responseCode == 0 || request.responseCode == (long)System.Net.HttpStatusCode.OK))
    {
        WrapperClass yourClassList = new WrapperClass();
        YourClassList.members = JsonUtility.FromJson<YourClass>(request.downloadHandler.text);

        var bytes = System.Text.Encoding.UTF8.GetBytes(JsonUtility.ToJson(instance));
        File.WriteAllBytes(Application.persistentDataPath + "/SubDirectory/" + Path.GetFileName(path), bytes);
    }

    request.Dispose();
}

Hope that clears things up for anyone else having the same issue.