brotliDecodeFile function

Future<Uint8List> brotliDecodeFile(
  1. String path, {
  2. BrotliDecodeOptions options = const BrotliDecodeOptions(),
})

Decompresses the Brotli stream stored in path.

The file is read in _fileChunkSize chunks and pushed through the streaming BrotliDecoder; memory use is proportional to the decompressed size, not the compressed size.

The stream is validated strictly: trailing bytes after a complete Brotli stream raise BrotliException (unusedBytesAfterEnd), matching brotliDecompress.

Implementation

Future<Uint8List> brotliDecodeFile(
  String path, {
  BrotliDecodeOptions options = const BrotliDecodeOptions(),
}) async {
  final file = await openBytesFile(path, create: false, readOnly: true);
  try {
    final decoder = BrotliDecoder(options: options);
    final output = Uint8List(_fileChunkSize);
    final builder = BytesBuilder(copy: false);
    var fileOffset = 0;
    var eof = false;
    var done = false;
    while (!done) {
      if (!eof) {
        final input = Uint8List(_fileChunkSize);
        final read = await file.readAt(fileOffset, input);
        if (read <= 0) {
          eof = true;
          decoder.closeInput();
        } else {
          fileOffset += read;
          decoder.addInput(
            read == input.length
                ? input
                : Uint8List.sublistView(input, 0, read),
          );
        }
      }
      final status = _pump(decoder, builder, output);
      if (status == BrotliStatus.done) {
        done = true;
        break;
      }
      if (status == BrotliStatus.needMoreInput) {
        if (eof) {
          throw BrotliException(
            BrotliErrorCode.truncatedInput,
            'file ended before the Brotli stream completed',
            inputOffset: decoder.consumedInput,
          );
        }
        continue;
      }
    }
    return builder.takeBytes();
  } finally {
    await file.close();
  }
}