Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unable to load file on android

Discussion in 'Android' started by Squirner, Oct 18, 2018.

  1. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    I am saving a data file with information about levels such as the size of the map to one of the paths.

    Code (CSharp):
    1. FilePaths[SaveFileType.LevelInfo] = Path.Combine(Application.streamingAssetsPath, "LevelsInfo.dat");
    2. FilePaths[SaveFileType.LevelInfo] = Path.Combine(Application.dataPath, "LevelsInfo.dat");
    But when I build the application for Android platform and test it on my phone, it doesn't load the data.

    I have tried a couple of things from this thread:
    https://forum.unity.com/threads/cant-use-json-file-from-streamingassets-on-android-and-ios.472164/
    Such as trying it without using File.Exists() or saving and loading the data to dataPath instead of streamingAssetsPath. But it didn't change anything. While loading and saving the data works fine on a "PC, Mac, Linux" build and while testing it in Unity.

    I hope anyone can give any information about creating a data file in Unity editor and saving this with the build.
     
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    On Android these directories are inside .apk itself, so File class can not be used to access them, since it only can read files from disk, but not from inside zip files.
    You can read files from these directories using UnityWebRequest. You can't write to them, they are read-only.
     
    Squirner and Yury-Habets like this.
  3. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    Does that mean you will need a internet connection to use that function?
     
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    No, you don't need internet connection to read local files with UnityWebRequest.
     
    Squirner likes this.
  5. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    I am not sure if I am getting this.
    Code (CSharp):
    1.     static IEnumerator DownloadFile(string filePath)
    2.     {
    3.         var uwr = new UnityWebRequest(filePath);
    4.         uwr.downloadHandler = new DownloadHandlerFile(filePath);
    5.         yield return uwr.SendWebRequest();
    6.         Debug.Log("File successfully downloaded and saved to " + filePath);
    7.     }
    Does it mean I can get/download the file with that DownloadFile methode example and then load it with File.Open as I did with the code for PC application:

    Code (CSharp):
    1.     public static void Load(SaveFileType fileType)
    2.     {
    3.         //try
    4.         {
    5.             BinaryFormatter bf = new BinaryFormatter();
    6.             FileStream file = File.Open(FilePaths[fileType], FileMode.Open);
    7.  
    8.             switch (fileType)
    9.             {
    10.                 case SaveFileType.LevelInfo:
    11.                     {
    12.                         LevelsInfoData data = (LevelsInfoData)bf.Deserialize(file);
    13.                         LevelManager.LevelsInfo = data.InfoAllLevels;
    14.                         break;
    15.                     }
    16.                 case SaveFileType.PlayerScore:
    17.                     {
    18.                         PlayerScoreData data = (PlayerScoreData)bf.Deserialize(file);
    19.                         LevelManager.TimeScores = data.TimeScores;
    20.                         break;
    21.                     }
    22.             }
    23.             file.Close();
    24.  
    25.             Debug.Log(fileType + " succefully loaded.");
    26.             return;
    27.         }
    28.         //catch { }
    29.     }
    30.  
    Because I am getting the following error when I am trying that:
    SerializationException: Attempting to deserialize an empty stream.

    MAIN PROBLEM:
    I want to save a file with data with the build so the application comes with that data and can load it when ever needed. This shows to be quite a struggle on Android.
     
    Last edited: Oct 20, 2018
  6. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    No, what you do is not correct.
    DownloadHandlerFile stores downloaded bytes to a given file. Now your code loads data from file and stores it to the same file. If you want to use .NET streams, you need to give DownloadHandlerFile a different path (and a writable one).
    If the file you are loading is not large, then it's probably better to use DownloadHandlerBuffer instead to load entire file to memory and then use MemoryStream.
     
    Squirner likes this.
  7. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    It is working now in the Unity editor. Gotta say now that I get it, I see that those were some simple mistakes I made... :D BUT, its still not working on android :confused:

    Changed code:
    Code (CSharp):
    1.     static IEnumerator DownloadFile(string filePath, string savePath)
    2.     {
    3.         UnityWebRequest uwr;
    4.         uwr = new UnityWebRequest(filePath);
    5.         uwr.downloadHandler = new DownloadHandlerFile(savePath);
    6.         yield return uwr.SendWebRequest();
    7.         Debug.Log(filePath + " File successfully downloaded and saved to " + savePath);
    8.     }
     
    Last edited: Oct 22, 2018
  8. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    What are the actual paths passed in?
     
    Squirner likes this.
  9. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    Oh yes forgot to mention
    Save path: Path.Combine(Application.dataPath, "LevelsInfo.dat")
    File path: Path.Combine(Application.streamingAssetsPath, "LevelsInfo.dat")
     
  10. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    That explains it. You can't save files to dataPath, that is a read-only location. Save them to persistentDataPath instead, that one is writable.
     
    Squirner likes this.
  11. Squirner

    Squirner

    Joined:
    Apr 28, 2016
    Posts:
    14
    First the persistentDataPath didn't work either, because I was still loading all 3 paths including the streamingAssetsPath. Somehow this caused problem again, but now I got it working by just loading persistentDataPaths and only downloading (with UnityWebRequest) from streamingAssetsPath.

    Thanks for your help Aurimas-Cernius :D