【发布时间】:2016-07-22 20:07:19
【问题描述】:
我正在尝试从大小约为 1.7 GB 的网络提要中反序列化 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"
}
}
【问题讨论】:
-
64 位应用程序应该可以正常工作。请确保您没有以 x86 运行。
-
~1.7 GB看来您的内存不足了。解决方案?不要那样做。如何?更好的设计。像什么?很多东西。给我一个。增量处理文件,不要尝试将其全部加载到内存中。如何。依靠。这就是人们雇用开发人员的原因:/ -
不要试图一次读完整本书。 StreamReader 的全部意义在于您可以流式传输数据。您不必一次获得全部内容。做 ReadLine 什么的。如果您需要在应用程序获取大量文件时保持响应,请考虑使用 async/await。
-
Anthony,您的示例 JSON 不是有效的 JSON,因为它不能有多个根对象。见here。