Json file not found after the Build

后端 未结 1 1827
清歌不尽
清歌不尽 2021-01-26 16:15

I\'d like to find where the json file is saved. In the editor mode I can find it. However, when I make the build of the game, I cannot find it.

I\'m using this script t

相关标签:
1条回答
  • 2021-01-26 16:56

    Files from persistentDataPath afaik will not be packed automatically into the built application.

    But the StreamingAssets are.

    The built application can load the Asset at this address.

    So what I usually do is using the Application.streamingAssetsPath while still being in the Editor. This is the same as simply putting a file into the folder Assets/StreamingAssets.

    I prefer this I general since I don't want my development application bloating some files into any folder hidden on the Windows PC but instead within the according project's Asset folder.

    Then on runtime after a build this folder is read-only and not visible/accessible on the device.

    So I check if the according file exists in the persistentDataPath.

    • If yes read I from there.
    • If not then rather read it once from the streamingAssetsPath and copy it into the persitentDataPath.

    Another important point:

    Do never use +"/"+ for file paths

    rather use Path.Combine which uses automatically the correct platform specific path separator symbol!


    The code depends a bit which is your target platform since the

    It is not possible to access the StreamingAssets folder on WebGL and Android platforms. No file access is available on WebGL. Android uses a compressed .apk file. These platforms return a URL. Use the UnityWebRequest class to access the Assets.

    I will only add the code for standalone (UWP) because I have not much experience with Android but it should be the same just using a Coroutine and UnityWebRequest for reading the streamingAssetsPath

    So in code it could be something like e.g.

    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    ...
    
    private string DataFolder
    {
    #if UNITY_EDITOR
        return Application.streamingAssetsPath;
    #else
        return Application.persitentDataPath;
    #endif
    }
    
    private string GetFilePath(string fileName)
    {
        return Path.Combine(DataFolder, fileName);
    }
    
    //                  | Little typo here btw
    //                  v
    private void WriteTopFile(string fileName, string json)
    {
        string filePath = GetFilePath(fileName);
    
        // Create folder if not exists
        if(!Directory.Exists(DataFolder)
        {
            Directory.CreateDirectory(DataFolder);
        }
    
        using(var fileStream = new FileStream(filePath, FileMode.Create))
        {
            using (StreamWriter writer = new StreamWriter(fileStream))
            {
                writer.Write(json);
            }
        } 
    
    #if UNITY_EDITOR
        AssetDataBase.Refresh();
    #endif
    }
    

    Now when reading as said before include a check if file exists I persistent path or not:

    private string ReadFromFile(string fileName)
    {
        var filePath = GetFilePath(fileName);
        var output = "";
    
        Debug.Log($"Trying to read file {filePath}");
        if (File.Exists(filePath))
        {
            Debug.Log($"File found! Reading from {filePath}");
            using(StreamReader reader = new StreamReader(filePath))
            {
                output = reader.ReadToEnd();
            }
            return output;
        }
    
        // Otherwise rather try to read from streaming assets
        var altFilePath = Path.Combine(Application.streamingAssetsPath, fileName);
        Debug.LogWarning($"File not found! Instead trying to read file {altFilePath}");
    
        if(File.Exists(altFilePath)
        {
            // read from here but directly also write it back to persistentDataPath
            Debug.Log($"File found. Reading from {altFilePath}");
    
            // As mentioned for Android you would now do the rest in a Coroutine 
            // using a UnityWebRequest.Get              
    
            using(StreamReader reader = new StreamReader(altFilePath))
            {
                output = reader.ReadToEnd();
            }
    
            // Now before returning also write it to persistentDataPath
            WriteTopFile(fileName, output);
            return output;
        }
    
        // If this also fails you didn't put such a file to `Assets/StreamingAssets` before the build
        Debug.LogError($"File also not found in {altFilePath}/n/nRemember to play it in 'Assets/StreamingAssets' before building!");
        return output;
    }
    

    Note: Currently I'm only on the phone so no warranty but I hope the idea gets clear already :)

    0 讨论(0)
提交回复
热议问题