在执行任何其他过滤器后,以1gb的ram解析json对象并提供System.OutOfMemoryException

时间:2018-12-18 04:44:13

标签: c# json.net

public void ReadJsonFile()
{
    try
    {
        string json = string.Empty;
        using (StreamReader r = new StreamReader(val))
        {
            json = r.ReadToEnd();
            var test = JObject.Parse(json);
            JArray items = (JArray)test["locations"];
            int length = items.Count;

            data = new List<Info>();
            for (int i = 0; i < items.Count; i++)
            {
                var d = test["locations"][i]["timestampMs"];
                double dTimeSpan = Convert.ToDouble(d);
                DateTime dtReturn = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Math.Round(dTimeSpan / 1000d)).ToLocalTime();
                string printDate = dtReturn.DayOfWeek.ToString() + "," + " " + dtReturn.ToShortDateString() + " " + dtReturn.ToShortTimeString();
                day = dtReturn.DayOfWeek.ToString();
                date = dtReturn.ToShortDateString();
                time = dtReturn.ToShortTimeString();
                var e = test["locations"][i]["latitudeE7"];
                var f = test["locations"][i]["longitudeE7"];
                var n = test["locations"][i]["accuracy"];
                accuracy = n.ToString();
               // getLocationByGeoLocation(e.ToString(), f.ToString());                   
                var g = test["locations"][i]["activity"] != null;
                if (g == true)
                {
                    JArray items1 = (JArray)test["locations"][i]["activity"];
                    int length1 = items1.Count;
                    while (j < items1.Count)
                    {
                        if (j == 0)
                        {
                            var h = test["locations"][i]["activity"][j]["activity"][j]["type"];
                            type = h.ToString();
                            j = 1;
                        }
                        else { }
                        j++;
                    }
                    j = 0;
                }
                else { }

                Info ddm = new Info(day, date, time, lat, longi, address, accuracy, type);
                data.Add(ddm);
                type = "";
            }
        }
        return;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

我正在尝试解析JSON文件。 val是我要解析的文件的名称。使用StreamReader,当我尝试使用jObject进行解析时,我正在读取每一行,我将占用1gb的内存,并给我System.OutOfMemoryException,如何使用小内存解析JObject。 请帮我解决这个问题,因为我对JSON不太了解。

2 个答案:

答案 0 :(得分:1)

请彻底了解JSON。 NewtonSof.JSON是非常著名的库,并且有据可查。让我们回到您的问题。如注释中所述,在尝试解析文件时,您有许多不必要的中间步骤。此外,您正在尝试一次分析一个大文件!首先,这是JSON的布局

public partial class Data
{
    [JsonProperty("locations")]
    public Location[] Locations { get; set; }
}

public partial class Location
{
    [JsonProperty("timestampMs")]
    public string TimestampMs { get; set; }

    [JsonProperty("latitudeE7")]
    public long LatitudeE7 { get; set; }

    [JsonProperty("longitudeE7")]
    public long LongitudeE7 { get; set; }

    [JsonProperty("accuracy")]
    public long Accuracy { get; set; }
}

在进行反序列化时,应该逐个对象地进行操作,而不是一次全部 以下假设您的streamData类型的对象组成,如果是,则由Location类型的对象组成,您必须对其进行更改

using (StreamReader streamReader = new StreamReader(val))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
    reader.SupportMultipleContent = true;

    var serializer = new JsonSerializer();
    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            var data = serializer.Deserialize<Data>(reader);
            //data.locations etc etc..
        }
    }
}

答案 1 :(得分:0)

我可以通过以下步骤修复System.OutOfMemoryException:

如果您不使用Visual Studio托管过程:

取消选中该选项:

Project->Properties->Debug->Enable the Visual Studio Hosting Process

如果问题仍然存在:

转到“项目”->“属性”->“构建事件”->“构建后事件”命令行,然后粘贴这两行

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)"  /LARGEADDRESSAWARE

现在,构建项目