readRDS=function(file = pipe('cat', 'rb'), ...) {
base::readRDS(file, ...)
}
saveRDS=function(object, file = pipe('cat', 'wb'), ...) {
base::saveRDS(object, file, ...)
}
I use the above function to read an RDS file from stdin and write an RDS file to stdout.
See below, one readRDS call works, the other doesn't. It depends on whether the rds file is written using pipe or not.
$ lr -e 'source("saveRDS.R"); saveRDS(1:3, file="/tmp/readRDS.rds");'
$ lr -e 'source("readRDS.R"); print(readRDS());' < /tmp/readRDS.rds
Error in base::readRDS(file, ...) : unknown input format
$ lr -e 'source("saveRDS.R"); saveRDS(1:3);' > /tmp/readRDS.rds
$ lr -e 'source("readRDS.R"); print(readRDS());' < /tmp/readRDS.rds
[1] 1 2 3
Why does it depend on the way the file is written? Is there a way to make readRDS from stdin always work whether the file is written via pipe or not?
CodePudding user response:
There seems to be a difference between compression between the two methods. Rather than reading from cat
in the readRDS
Try
readRDS=function(file = base::gzcon(base::file("stdin", "rb")), ...) {
base::readRDS(file, ...)
}
The gzcon
will do the compression if the gz magic number is found, otherwise it will just pass through the file normally. This should allow things to work in both cases.