How to write compressed (gzip) data to a file with Gjs and Gio

Hello,

I have an app that saves files being worked on by the user.
Currently these files are just regular text files (JSON).
I would like to save them compressed (gzip).

I looked at the gio converter documentation and have tried to put it in place, but no luck.
My overly simplistic attempt looks like this:

function compress(data) {
  const comp = Gio.ZlibCompressor.new(Gio.ZlibCompressorFormat.GZIP, -1);
  const te = new TextEncoder('utf-8');
  const td = new TextDecoder('utf-8');
  const len = encodeURI(data).split(/%..|./).length - 1;
  let outbuff = new Int8Array(len);
  const inbuff = te.encode(data);
  let res;
  res = comp.convert(inbuff, outbuff, 1);
  log(res);
  
  if (res[0] == 2) {
    res = comp.convert(inbuff, outbuff, 2);
    log(res);
  }
  
  return td.decode(outbuff);
}

This ends in the following error:
“JS ERROR: Gio.IOErrorEnum: Internal error: stream error”
trying to flush the data to the output array…

Are there any examples out there of using compression in gjs/javascript?
Any pointers on what I am doing wrong or what the error means?

Thanks in advance

This seems to do the trick…

function compress(data) {
  const te = new TextEncoder('utf-8');
  let compressed = Gio.MemoryOutputStream.new_resizable();
  let output = new Gio.ConverterOutputStream({
    base_stream: compressed,
    converter: new Gio.ZlibCompressor({
      format: Gio.ZlibCompressorFormat.GZIP,
    }), 
  });
  output.splice(Gio.MemoryInputStream.new_from_bytes(te.encode(data)),
                  Gio.OutputStreamSpliceFlags.CLOSE_SOURCE,
                  null);
  output.flush(null);
  output.close(null);

  
  return compressed.steal_as_bytes().get_data();
}

Now I need to see how to decompress it…

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.