读取Json字符串时发生OutOfMemoryException



我正试图从大约1.7 GB大小的web提要中反序列化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。有人看到我不能转换可能做错了什么吗?我用这个问题来绕过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"
    }
}

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

基本上,你可以将stream.ReadLine()附加18次(假设所有对象都像你发布的一样编写)

如果不是,则应该使用stream.ReadLine()来计算打开和关闭的花括号,直到到达每个对象的末尾,并以这种方式分别序列化它们。

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

相关内容

  • 没有找到相关文章

最新更新