Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to gzip a string to a file so that it can be unzipped with regular gzip?

I want to serialize R objects as JSON for other programs to use, and gzip them for efficient transport. So I run

data <- list(foo = "bar")
readr::write_file(jsonlite::as_gzjson_b64(data), "foo")

Actually, I want to print that base64 string as part of a log message, but let's work with files for now.

However, decompression fails:

❯ base64 -d < foo | gzip --decompress

gzip: stdin: not in gzip format

I've been able to narrow this down to this:

readr::write_file(memCompress("foobar", "gzip"), "foo.gz")
❯ gzip --decompress < foo.gz
x�K��OJ�z
 ❯ gzip --decompress < foo.gz | hexyl
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 78 9c 4b cb cf 4f 4a 2c ┊ 02 00 08 ab 02 7a       │x×K××OJ,┊•⋄•וz  │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

I found this in the docs of memCompress:

Support for the libdeflate library was added for R 4.4.0. It uses different code for the RFC 1950 ‘zlib’ format (and RFC 1952 for decompression), expected to be substantially faster than using the reference (or system) zlib library. It is used for type = "gzip" if available.

So I also tried libdeflate-gunzip instead of gzip --decompress -- same exact output.

What's going on here, and more importantly: How do I create a proper base64-encoded gzip-ed JSON string in R?

Versions

  • R 4.5.1
    • jsonlite 2.0.0
    • readr 2.1.5
  • gzip 1.14-modified
like image 941
Raphael Avatar asked Sep 21 '25 12:09

Raphael


1 Answers

It appears that jsonlite::as_gzjson_b64 uses gzip compression, but doesn't produce a gzip format file. You can reverse the process using jsonlite::parse_gzjson_b64. For example:

data <- list(foo = "bar")
readr::write_file(jsonlite::as_gzjson_b64(data), "foo")
jsonlite::parse_gzjson_b64(readr::read_file("foo"))
#> $foo
#> [1] "bar"

Created on 2025-09-09 with reprex v2.1.1

You say you want other programs to use this. If they are not written in R, you'll probably have to use other methods to convert to base64 and compress them, e.g. gzcon() for compression, base64enc::base64encode() for converting to ASCII.

Edited to add:

Here's an example of the second approach:

data <- list(foo = "bar")

json <- jsonlite::toJSON(data)
con1 <- gzcon(file("foo.gz", "wb"))
writeLines(json, con1)
close(con1)

con2 <- file("foo.gz", "rb")
writeLines(base64enc::base64encode(con2), "foo.gz.b64")
close(con2)
unlink("foo.gz")

Now you can do this:

$ base64 -d < foo.gz.b64 | gzip --decompress
{"foo":["bar"]}
like image 195
user2554330 Avatar answered Sep 23 '25 00:09

user2554330