【发布时间】:2019-03-10 18:50:03
【问题描述】:
我正在尝试读取这个 JSON 文件。 If it looks messy, here is a Pastebin of the JSON。 If the code looks messy, here is the Pastebin for that as well!(忽略 DeserializeQuestions() 函数中的 return 语句)。当我在编辑器中测试它时,它可以完美运行,但是当我在 Android 设备上测试它时它会中断。
我收到这条与伏尼契手稿一样神秘的错误消息:
{
"Questions": {
"0": [ "Are all of these questions temporary?", "Yes they are", "No", "No nr 2", "No nr 3" ],
"1": [ "Roughly how tall is Mount Everest?", "8848 meters", "9343 meters", "8.322 km", "73000 mm" ],
"2": [ "What are the worlds most populated countries?", "China, India and the US", "China, Russia and the US", "Russia, Brazil and the Soviet Union", "England, Russia and the US" ],
"3": [ "What is the highest mountain top in Stord?", "Mehammarsåta", "Mennene", "Utslettefjellet", "Siggjo" ],
"4": [ "What field did Stephen Hawking mainly study?", "Theoretical physics", "Relative physics", "Imaginary physics", "The gravity of your mom" ],
"5": [ "What field did Stephen Hawking mainly study?", "Theoretical physics", "Relative physics", "Imaginary physics", "The gravity of your mom" ],
"6": [ "What is Asgeir Asgeirson's favorite car manufacturar?", "Mercedes", "Ferrari", "Lamborghini", "
}
空间
using UnityEngine;
using System.IO;
using System.Collections.Generic;
using System;
using Newtonsoft.Json.Linq;
public class JsonFileWriter : MonoBehaviour
{
public GameController gameController;
public Settings settings;
public List<Dictionary<string, string>> allQuestions = new List<Dictionary<string, string>>();
public string path;
public string pathGameData;
public void Start()
{
path = "jar:file://" + Application.dataPath + "!/assets/data.json";
#if UNITY_EDITOR
path = Path.Combine(Application.streamingAssetsPath, "data.json");
#endif
pathGameData = Path.Combine(Application.persistentDataPath, "gameData.json");
//List<JsonString> temp = new List<JsonString>();
//temp.Add(new JsonString(new string[]{ "The question","The correct answer","Answer 1","Answer 2","Answer 3"}));
//SerializeData();
DeserializeQuestions();
}
public void SerializeGameData(GameData data)
{
System.DateTime epochStart = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
string cur_time = (int)(System.DateTime.UtcNow - epochStart).TotalSeconds + "";
data.date = cur_time;
if (!File.Exists(pathGameData))
{
File.WriteAllText(pathGameData, "");
}
string containerJson = File.ReadAllText(pathGameData);
GameDataContainer container = new GameDataContainer();
container.container = new List<GameData>();
if(containerJson != "")
{
container = JsonUtility.FromJson<GameDataContainer>(containerJson);
}
container.container.Add(data);
if(container.container.Count > settings.save_this_many_games)
{
int lowest = (int)(System.DateTime.UtcNow - epochStart).TotalSeconds;
foreach(GameData s in container.container)
{
if(Int32.Parse(s.date) < lowest)
{
lowest = Int32.Parse(s.date);
}
}
for (int i = container.container.Count - 1; i >= 0; i--)
{
if(Int32.Parse(container.container[i].date) == lowest)
{
container.container.Remove(container.container[i]);
}
}
}
containerJson = JsonUtility.ToJson(container);
File.WriteAllText(pathGameData, containerJson);
}
public void DeserializeQuestions()
{
string json;
if (Application.platform == RuntimePlatform.Android)
{
WWW reader = new WWW(path);
while (!reader.isDone) { }
json = reader.text;
}
json = File.ReadAllText(path);
JObject jo = JObject.Parse(json);
Dictionary<string, List<string>> values = jo.SelectToken("Questions", false).ToObject<Dictionary<string, List<string>>>();
foreach(var kv in values)
{
Dictionary<string, string> temp = new Dictionary<string, string>();
int i = 0;
foreach(string s in kv.Value)
{
temp.Add(i + "", s);
i++;
}
allQuestions.Add(temp);
}
}
}
[Serializable]
public class GameData
{
public string date;
public string questions;
public List<string> playerScoresNames;
public List<int> playerScoresScores;
public List<string> playerStatesNames;
public List<int> playerStatesStates;
}
[Serializable]
public class GameDataContainer
{
public List<GameData> container;
}
空间
03-10 20:18:11.653: E/Unity(28401): JsonReaderException: Unexpected character encountered while parsing value: ?. Path '', line 0, position 0.
03-10 20:18:11.653: E/Unity(28401): at Newtonsoft.Json.JsonTextReader.ParseValue () [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at Newtonsoft.Json.JsonTextReader.Read () [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at Newtonsoft.Json.Linq.JObject.Load (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Linq.JsonLoadSettings settings) [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at Newtonsoft.Json.Linq.JObject.Parse (System.String json, Newtonsoft.Json.Linq.JsonLoadSettings settings) [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at Newtonsoft.Json.Linq.JObject.Parse (System.String json) [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at JsonFileWriter.DeserializeQuestions () [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401): at JsonFileWriter.Start () [0x00000] in <filename unknown>:0
03-10 20:18:11.653: E/Unity(28401):
03-10 20:18:11.653: E/Unity(28401): (Filename: Line: -1)
【问题讨论】:
-
只是出于好奇,你为什么要把
JsonUtility.FromJson和JObject.Parse混在一起?为什么不为这些问题建立一个数据模型并使用JsonUtility.FromJson呢?它不处理字典吗? -
正确!据我所知,JsonUtility 不处理字典!
-
您的文件可能以BOM 开头。
File.ReadAllText()应该处理并删除它,但它可能在 unity3d/Android 上无法正常工作。所以你可以尝试从this answer 到Strip Byte Order Mark from string in C# 的变通方法。打印json字符串的前 100 个左右字节的数值会更清楚。 -
打印
json字符串的前 100 个左右字节的数值可以清楚地说明这一点。相关:Why is File.ReadAllBytes result different than when using File.ReadAllText?. -
哦,好吧,在您最近的编辑中,很明显您正在使用名为
WWW的东西在 Android 上阅读您的文字,而不是File.ReadAllText()。我根本不知道这个类,但无论如何,现在更有可能的是,在字符串的开头留下了 BOM。
标签: android json unity3d json.net