将字符串反序列化为JSON对象时出错

时间:2019-09-14 15:51:03

标签: c# php json unity3d json.net

我有一个php文件,该文件读取.txt文件并将其通过php服务器发送到c#统一脚本。下面是显示前三行的文本文件的片段:

{ "lemma" : "aljotta", "gloss" : "Fisħ soup" }
{ "lemma" : "arguzin", "gloss" : "Slave driver" }
{ "lemma" : "armunjaka", "gloss" : "Armunjaka" }

这是php脚本:

<?php
$file = fopen("lemmas.txt", "r");
echo fread($file, filesize("lemmas.txt"));
fclose($file);
?>

在c#脚本中,返回文本,并将每一行分成一个数组(字符串[]行)插槽,如下所示:

IEnumerator GetTextFromFile()
    {
        bool succcessful = true;
        WWWForm form = new WWWForm();
        WWW www = new WWW("http://localhost:9000/tounity.php", form);

        yield return www;

        if(www.error != null)
        {
            succcessful = false;
        }
        else
        {
            succcessful = true;
        }

        if (succcessful)
        {
            populateWordList(www.text);
        }
    }

 void populateWordList(string text)
    {
        string[] textArray = text.Split('\n');
        wordsList = gameDatabase.GetWords(textArray);
    }

然后将数组传递给一个方法,该方法将每行反序列化为GameDatabase类的对象,如下图所示:

public string lemma { get; set; } 
public string gloss { get; set; }

public GameDatabase(string lemma, string gloss)
{
    this.lemma = lemma;
    this.gloss = gloss;
}

public  ArrayList GetWords(string[] lines)
{
    foreach (string line in lines)
    {

        GameDatabase gd = JsonConvert.DeserializeObject<GameDatabase>(line);
        lemmasAndGlossesList.Add(new GameDatabase(gd.lemma, gd.gloss));
    }

    foreach(GameDatabase line in lemmasAndGlossesList)
    {
        Debug.Log(line.lemma + "------" + line.gloss);
    }

    return lemmasAndGlossesList;
}

错误发生在GameDatabase gd = JsonConvert.DeserializeObject<GameDatabase>(line);中,并返回

JsonReaderException: Unexpected character encountered while parsing value: . Path '', line 0, position 0.

我进行了广泛的搜索,但是没有找到任何有效的方法。任何帮助将不胜感激。值得注意的是,不使用php将文本文件直接加载为unity时,不会发生此问题。


编辑


使用vs调试器时,这是要反序列化的行中的值:

enter image description here

但是Visual Studio 2019的JSON可视化工具报告此:

enter image description here

3 个答案:

答案 0 :(得分:2)

感谢Jonathon K的评论,您的答复我们可以看到PHP脚本返回的数据以with a BOM开始:前三个字节。 This nice article说明了如何正确处理此类数据。简而言之:使用StreamReader读取数据。

这个小程序演示了如何处理您的数据:

using System;
using Newtonsoft.Json;
using System.IO;


public class Program
{
    public static void Main()
    {
        var bytes = new byte[] {
            0xEF,0xBB,0xBF,0x7B,0x20,0x22,0x6C,0x65,0x6D,0x6D,0x61,0x22,
            0x20,0x3A,0x20,0x22,0x61,0x72,0x67,0x75,0x7A,0x69,0x6E,0x22,
            0x2C,0x20,0x22,0x67,0x6C,0x6F,0x73,0x73,0x22,0x20,0x3A,0x20,
            0x22,0x53,0x6C,0x61,0x76,0x65,0x20,0x64,0x72,0x69,0x76,0x65,
            0x72,0x22,0x20,0x7D};

        string json;
        using(var ms = new MemoryStream(bytes))
        using(var sr = new StreamReader(ms))
        {
            json = sr.ReadToEnd();
            Console.WriteLine(json);
        }

        // I'm using dynamic here. In your case you can use GameDatabase
        dynamic obj = JsonConvert.DeserializeObject(json);
        Console.WriteLine(obj.lemma);
    }
}

输出:

{ "lemma" : "arguzin", "gloss" : "Slave driver" }
arguzin

答案 1 :(得分:0)

我不知道C#语法,但这可以工作。

更改您的JSON文件。

[
    { "lemma" : "aljotta", "gloss" : "Fisħ soup" },
    { "lemma" : "arguzin", "gloss" : "Slave driver" },
    { "lemma" : "armunjaka", "gloss" : "Armunjaka" }
]

JsonConvert.DeserializeObject应用于www.text

for (GameDatabase line in JsonConvert.DeserializeObject<GameDatabase[]>(www.text)){
    Debug.Log(line.lemma + "------" + line.gloss);
}

也许我的C#语法错误,但是我想让你理解我的想法

答案 2 :(得分:0)

我认为使用JsonConvert可能会使反序列化出错。

相反,请阅读此文档并尝试使用Unity功能: https://docs.unity3d.com/Manual/JSONSerialization.html

对于初学者,如果要使用它们在Unity中反序列化JSON,则定义的引理和光泽不正确。查看此答案以获取更多信息: Serialize and Deserialize Json and Json Array in Unity