2

I would like to efficiently deserialize JSON object which contains a nested array of JSON objects.

For example, a JSON directory listing could contain a root JSON file system object with a recursive array of file system objects.

{
    "bytes": 0,
    "path": "/Public",
    "is_dir": true,
    "contents": [
        {
            "bytes": 0,
            "modified": "Mon, 18 Jul 2011 20:13:43 +0000",
            "path": "/Public/1.txt",
            "is_dir": false
        },
        {
            "bytes": 0,
            "modified": "Mon, 18 Jul 2011 20:13:43 +0000",
            "path": "/Public/2.txt",
            "is_dir": false
        }
    ]
}

The corresponding C# class would look something like this

class JsonFileInfo
{
    public string Path;
    public long Bytes;
    public string Modified;
    public bool IsDir;
    public List<JsonFileInfo> Contents;
}

I've tried the .NET DataContractJsonSerializer e.g.

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RainstormFileInfo));
JsonFileInfo jfi = (JsonFileInfo)serializer.ReadObject(responseStream);

and I've also tried the JSON.NET JsonSerializer + JsonTextReader e.g.

JsonReader reader = new JsonTextReader(new StreamReader(responseStream))
JsonSerializer serializer = new JsonSerializer();
JsonFileInfo jfi = serializer.Deserialize<JsonFileInfo>(reader);

but both frameworks read the entire contents JSON sub-array into memory in one fell swoop of deserialization.

How can I read this JSON result from a stream one JsonFileInfo object at a time?

dbc
  • 104,963
  • 20
  • 228
  • 340
Keith Morgan
  • 721
  • 7
  • 17
  • When you say efficiently what do you mean? shortest time? least resources? least lines of code? each could very well have a different solution –  Jan 21 '13 at 16:25
  • I reckon you'll have to write a custom de/serializer – Paul Sullivan Jan 21 '13 at 16:25
  • Good point. By efficient I mean with the smallest memory footprint possible. That's why I don't want to read the whole structure into memory at once. – Keith Morgan Jan 21 '13 at 21:07
  • Just my 2c; given that you're reading from a stream, how do you even know how to read one object's worth of bytes at a time, since the number of objects in Contents is unknown...if the structure was guaranteed to be a fixed size then maybe you could read the stream N bytes at a time but honestly, I don't think this will even end up as efficient as reading the entire thing into memory at once,since what you save on memory you'll lose on cpu... – Stephen Byrne Jan 22 '13 at 00:45

1 Answers1

0

There is now a library available to do exactly what you're looking for. It will read JSON one byte at a time and return the result. Full description and usage examples here.

It may allow you to avoid reinventing the wheel.

Essentially, this library allows you to parse either the full JSON object, or to target nested objects. It's a very efficient way of parsing JSON in either case, and is faster than JSON.NET.

Paul Mooney
  • 1,576
  • 12
  • 28
  • This exactly the kind of library I was looking for. – Keith Morgan Nov 17 '14 at 11:03
  • No problem, Keith. I'm happy to walk through in more detail, if necessary. – Paul Mooney Nov 17 '14 at 15:42
  • 1
    Please make sure you mention the fact you're linking to your own blog when providing the description and usage examples.. – AverageHomosapien Jul 19 '22 at 12:05
  • Ideally this answer should be updated to demonstrate the techniques your library used to solve this problem, so that people can understand the actual solution. Then the answer could be supplemented with a link to your library, disclosing your affiliation, for users who are willing to add your library as a dependency to their project. – user229044 Jul 19 '22 at 14:11