Чтение определенного объекта из json как потока с использованием JsonTextReader или любой другой альтернативы - PullRequest
0 голосов
/ 10 декабря 2018

Необходимо прочитать большой файл как часть JSON из HTTP Post в Web API.Поскольку сам файл является частью JSON.пример:

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

Мне нужно только искать объект вложения, но опять же «данные» здесь содержат большой файл.Может быть csv, pdf, JSON или image, и самое важное будет иметь большой размер> 1 ГБ.

Согласно анализу, способному прочитать это с помощью этих оболочек

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.

Есть ли способ прочитать большие данные в виде потока через другую библиотеку или одну и ту же библиотеку по-другому (хотя перегрузка недоступна)

...