您能否将表示 RDS 文件的 R 原始向量转换回 R 对象,而无需往返磁盘?

Can you convert an R raw vector representing an RDS file back into an R object without a round trip to disk?

我有一个 RDS 文件,该文件通过 curl::curl_fetch_memory()(通过 httr)上传然后下载 - 这为我提供了 R 中的原始向量。

有没有办法将代表 RDS 文件的原始向量读取到 return 原始 R 对象?还是必须先写入磁盘?

我有一个类似于下面的设置:

saveRDS(mtcars, file = "obj.rds")
# upload the obj.rds file 
...
# download it again via httr::write_memory()
...

obj
#   [1] 1f 8b 08 00 00 00 00 00 00 03 ad 56 4f 4c 1c 55 18 1f ca 02 bb ec b2 5d 
# ...
is.raw(obj)
#[1] TRUE

似乎 readRDS() 应该用来解压缩它,但它需要一个连接对象,我不知道如何从 R 原始向量创建连接对象 - rawConnection() 看起来很有希望但给了:

rawConnection(obj)
#A connection with                           
#description "obj"          
#class       "rawConnection"
#mode        "r"            
#text        "binary"       
#opened      "opened"       
#can read    "yes"          
#can write   "no"     
readRDS(rawConnection(obj))
#Error in readRDS(rawConnection(obj)) : unknown input format

查看 readRDS 看起来它在下面使用了 gzlib() 但无法使其与原始矢量对象一起使用。

如果它通过 httr::write_disk() -> curl::curl_fetch_disk() -> readRDS() 下载那么一切都很好,但是这是一个往返磁盘的过程,我想知道它是否可以针对大文件进行优化文件。

默认情况下,RDS 文件流是 gzip 压缩的。要读取原始连接,您需要手动将其包装成 gzcon:

con = rawConnection(obj)
result = readRDS(gzcon(con))

即使流 未被 gzip 压缩,这仍然有效。但不幸的是,如果使用不同的受支持压缩方法(例如 'bzip2')创建 RDS 文件,它会失败。不幸的是,R 似乎没有 gzcon 等价于 bzip2 或 xz。对于这些格式,唯一的办法似乎是将数据写入磁盘。

我遇到了完全相同的问题,对我来说,上述 gzcon 的答案不起作用,但是,我可以使用 rawConnection 直接将原始对象加载到 R 的内存中:

load(rawConnection(obj))