json_stream

A package for converting objects to JSON asynchronously through a byte stream.

This package is useful for encoding extremely large objects that would consume too much memory with a standard JsonEncoder.

To use this library you can either construct a JsonStreamWriter or use the static method JsonStreamWriter.convert.

Note that this library is slightly less performant than the default JSON encoder, it is only suitable in applications that serialize objects that can be streamed, not large objects already in memory.

The writer accepts a few extra things that the regular encoder doesn't:

  • Future<dynamic> - A future that is written when it completes.
  • Stream<String> - A stream of string parts, the resulting json contains a single string with each part concatenated.
  • dynamic Function() - A function that returns the result object (only called after previous objects are written).
  • Future<void> Function(JsonStreamWriter) - A function that writes directly to the writer.

Each of these will wait for the listener of the stream to be ready before writing, this allows you to only read an input stream as fast as the output stream accepts it (e.g. from disk to network) without excessive buffering.

Basic example:

import 'dart:async';
import 'dart:io';

import 'package:json_stream/writer.dart';

Future<void> main() async {
  // Prints {"numbers":"0123456789","letters":"abcdefghijklmnopqrstuvwxyz"}
  await stdout.addStream(
    JsonStreamWriter.convert({
      'numbers': Stream.periodic(
        const Duration(milliseconds: 100),
            (i) => '$i',
      ).take(10),
      'letters': () async* {
        for (var i = 0; i < 26; i++) {
          yield '${String.fromCharCode(i + 0x61)}';
          await Future<void>.delayed(const Duration(milliseconds: 100));
        }
      },
    }),
  );
}

This can also be written as:

Future<void> main() async {
  // Prints {"numbers":"0123456789","letters":"abcdefghijklmnopqrstuvwxyz"}
  final writer = JsonStreamWriter();
  final done = stdout.addStream(writer.stream);
  await writer.startMap();
  await writer.writeEntry(
    'numbers',
    Stream.periodic(const Duration(milliseconds: 100), (i) => '$i').take(10),
  );
  await writer.writeEntry(
    'letters',
        () async* {
      for (var i = 0; i < 26; i++) {
        yield '${String.fromCharCode(i + 0x61)}';
        await Future<void>.delayed(const Duration(milliseconds: 100));
      }
    },
  );
  await writer.end();
  await done;
}

Libraries

json_stream
writer