2016-07-22 95 views
0

我試圖從大小約爲1.7 GB的Web Feed中反序列化Json數據。我開始用下面的代碼:OutOfMemoryException讀取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" 
    } 
} 
+0

64位應用應該可以正常工作。請確保你沒有運行x86。 –

+1

'〜1.7 GB'看起來你內存不足。解?不要這樣做。怎麼樣?更好的設計。像什麼?事物的多少。給我一個。逐步處理文件,不要嘗試將其全部加載到內存中。怎麼樣。依靠。這就是爲什麼人們聘請開發人員:/ – Will

+0

安東尼,如果你的新問題是「不能隱式轉換類型'列表'到'RootObject'」那麼這應該是你的問題,否則像@Will這樣的人會嘗試回答「內存不足「而不是你真正的問題,」爲什麼不是這種反序列化?「。 – Quantic

回答

0

你應該創建一些規則,你如何分隔每個對象,並seperately序列化。

基本上你可以追加stream.ReadLine() 18倍(假設所有對象正是這樣寫你貼)

如果不是你應該使用stream.ReadLine()算你打開和關閉大括號,直到你達到每年年底對象並將它們分別序列化。

我猜測有更好的方法,但這些都很簡單,應該可以解決你的問題...