读取Json字符串时出现OutOfMemoryException

时间:2016-07-22 20:07:19

标签: c# ssis json.net

我正在尝试从大小为1.7 GB的Web Feed反序列化Json数据。我从以下代码开始:

public override void CreateNewOutputRows()
{

    //Set Webservice URL
    string wUrl = "webserviceURLgoeshere";

    try
    {

        RootObject outPutResponse = GetWebServiceResult(wUrl);

        foreach (Impression imp in outPutResponse.impressions)
        {

            ImpressionsSheetOutputBuffer.AddRow();
            ImpressionsSheetOutputBuffer.token = imp.token;
            ImpressionsSheetOutputBuffer.userid = imp.userid;
            ImpressionsSheetOutputBuffer.itemid = imp.itemid;
            ImpressionsSheetOutputBuffer.view = imp.view;
            ImpressionsSheetOutputBuffer.imageguid = imp.imageguid;
            ImpressionsSheetOutputBuffer.bytes = imp.bytes;
            ImpressionsSheetOutputBuffer.format = imp.format;

            ImpressionIDBuffer.AddRow();
            ImpressionIDBuffer.oid = imp.imId.oid;

            ImpressionParamsBuffer.AddRow();
            ImpressionParamsBuffer.origformat = imp.imParams.origFormat;
            ImpressionParamsBuffer.size = imp.imParams.size;

            ImpressionTimeBuffer.AddRow();
            ImpressionTimeBuffer.numLong = Int32.Parse(imp.imTime.numLong);
        }
    }

    catch (Exception e)
    {
        FailComponent(e.ToString());
    }
}

private RootObject GetWebServiceResult(string wUrl)
{

    HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(wUrl);
    HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
    RootObject jsonResponse = null;

    try
    {

        if (httpWResp.StatusCode == HttpStatusCode.OK)
        {

            Stream responseStream = httpWResp.GetResponseStream();
            string jsonString = null;

            using (StreamReader reader = new StreamReader(responseStream))
            {
                jsonString = reader.ReadToEnd();
                reader.Close();
            }

            JavaScriptSerializer sr = new JavaScriptSerializer();
            jsonResponse = sr.Deserialize<RootObject>(jsonString);

        }

        else
        {
            FailComponent(httpWResp.StatusCode.ToString());

        }
    }

    catch (Exception e)
    {
        FailComponent(e.ToString());
    }
    return jsonResponse;
}

private void FailComponent(string errorMsg)
{
    bool fail = false;
    IDTSComponentMetaData100 compMetadata = this.ComponentMetaData;
    compMetadata.FireError(1, "Error Getting Data From Webservice!", errorMsg, "", 0, out fail);

}

}

public class Id {

    public string oid { get; set; }
}

public class Params {

    public string origFormat { get; set; }
    public string size { get; set; }
}

public class Time {

    public string numLong { get; set; }
}

public class Impression {

    public Id imId { get; set; }
    public string token { get; set; }
    public string userid { get; set; }
    public string itemid { get; set; }
    public string view { get; set; }
    public string imageguid { get; set; }
    public int bytes { get; set; }
    public string format { get; set; }
    public Params imParams { get; set; }
    public Time imTime { get; set; }
}

public class RootObject {
    public List<Impression> impressions { get; set; }
}

但是,StreamReader ReadToEnd方法是抛出异常的地方,因为数据的大小太大。

我尝试将该代码更改为以下内容:

Stream responseStream = httpWResp.GetResponseStream();

StreamReader reader = new StreamReader(responseStream);

using (var myjson = new JsonTextReader(reader))
{
    JsonSerializer myserialization = new JsonSerializer();
    return (List<RootObject>)myserialization.Deserialize(myjson, typeof(List<RootObject>));
}

这给了我一个错误,我不能隐式地将类型List<RootObject>转换为RootObject。有谁看到我可能做错了我无法进行此转换?我使用this question来解决OutOfMemory异常,但现在它没有返回反序列化的项目。任何建议都将不胜感激。

修改 Json数据如下所示:

{
"_id": {
    "$oid": "000000000000000000000000"
    },
"token": "00000000-0000-0000-0000-000000000000",
"userId": "username",
"itemId": "00000000-0000-0000-0000-000000000000",
"view": "view1",
"imageguid": "00000000-0000-0000-0000-000000000000",
"bytes": 1000,
"format": "PNG",
"params": {
    "originalFormat": "tif",
    "size": "50x50"
    },
"time": {
    "$numberLong": "1458748200000"
    }
}
{
"_id": {
    "$oid": "100000000000000000000000"
     },
"token": "00000000-0000-0000-0000-000000000000",
"userId": "username",
"itemId": "00000000-0000-0000-0000-000000000000",
"view": "view1",
"imageguid": "00000000-0000-0000-0000-000000000000",
"bytes": 1000,
"format": "PNG",
"params": {
    "originalFormat": "tif",
    "size": "50x50"
    },
"time": {
    "$numberLong": "1458748200000"
    }
}

1 个答案:

答案 0 :(得分:0)

您应该创建一些规则来分隔每个对象,并将它们单独序列化。

基本上你可以追加stream.ReadLine() 18次(假设所有对象的写法与你发布的完全相同)

如果不是,则应使用stream.ReadLine()计算打开和关闭的大括号,直到到达每个对象的末尾,然后单独将它们序列化。

我猜有更好的方法,但这些很简单,应该可以解决你的问题......