使用JsonTextReader或任何其他替代方法从json作为流读取特定对象

时间:2018-12-10 14:30:16

标签: c# json stream json.net large-data

必须将大型文件作为JSON的一部分从HTTP Post读取到Web API。 由于File本身是JSON的一部分。 例如:

{
"type": "xxxx",
//other JSON,
 "attachment": {
    "mimetype": "text/csv",
    "extension": "csv",
    "data":{a,b,c,d,f}
} 

我只需要查找附件对象,但是这里的“数据”再次包含大文件。可以是csv,pdf,JSON或图像,最重要的是大于1GB的大容量。

根据分析结果,这些包装器可以读取

public class AttachmentParser 
             : JsonParser<Attachment>
{
    public AttachmentParser(Stream json, string jsonPropertyName)
        : base(json, jsonPropertyName)
    {
        Parse();
    }

    public override void Build(Attachment parsable, JsonTextReader reader)
    {
        if (reader.Value.Equals("extension"))
        {
            reader.Read();
            parsable.Extention = (string)reader.Value;
        }
        else if (reader.Value.Equals("data"))
        {
            reader.Read();
            parsable.Data = reader.Value;
        }
    }

    protected override bool IsBuilt(Attachment parsable, JsonTextReader reader)
    {
        var isBuilt = parsable.Extention != null && parsable.Data != null;
        return isBuilt || base.IsBuilt(parsable, reader);
    }

    private static MemoryStream SerializeToStream(object o)
    {
        MemoryStream stream = new MemoryStream();
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, o);
        return stream;
    }
}

Json Parser:

 public abstract class JsonParser<TParsable>
    where TParsable : class, new()
{
    private readonly Stream json;
    private readonly string jsonPropertyName;

    protected JsonParser(Stream json, string jsonPropertyName)
    {
        this.json = json;
        this.jsonPropertyName = jsonPropertyName;

        Result = new TParsable();
    }

    public TParsable Result { get; private set; }

    public abstract void Build(TParsable parsable, JsonTextReader reader);

    protected virtual bool IsBuilt(TParsable parsable, JsonTextReader reader)
    {
        return reader.TokenType.Equals(JsonToken.None);
    }

    protected void Parse()
    {
        using (var streamReader = new StreamReader(json))
        {
            using (var jsonReader = new JsonTextReader(streamReader))
            {
                do
                {
                    jsonReader.Read();
                    if (jsonReader.Value == null || !jsonReader.Value.Equals(jsonPropertyName))
                    {
                        continue;
                    }

                    var parsable = new TParsable();

                    do
                    {
                        jsonReader.r;
                    }
                    while (!jsonReader.TokenType.Equals(JsonToken.PropertyName) && !jsonReader.TokenType.Equals(JsonToken.None));

                    do
                    {
                        Build(parsable, jsonReader);
                        jsonReader.Read();
                    }
                    while (!IsBuilt(parsable, jsonReader));

                    Result = parsable;
                }
                while (!jsonReader.TokenType.Equals(JsonToken.None));
            }
        }
    }
}

查询: 这里JSONTextReader具有jsonReader.Read()方法,该方法确实逐个元素读取,但默认情况下作为对象读取。这将在内存中,并在此操作期间增加内存的更多负载。 曾经看过的重载不包含ReadAsStream方法。

是否可以通过不同的库或相同的库以不同的方式将大数据作为流读取(尽管没有重载)

0 个答案:

没有答案