Отправить R (гетерогенный) объект списка в виде двоичного файла в качестве ответа на запрос REST, используя сантехника - PullRequest
0 голосов
/ 05 ноября 2019

Я хотел бы отправить объект сложного гетерогенного списка в двоичном виде в ответ на запрос REST службе R (используя сантехника), чтобы при декодировании на другой стороне он преобразовывался обратно в свой первоначальный формат списка.

До сих пор мне удавалось сделать это, используя промежуточные файлы RDS, прочитав и слегка изменив Base64, кодирующий файл .Rda .

Ниже приводится описание MWE, объясняющее мои усилия и проблемы:

foodata <- list('a' = 1,
                'b' = 'hello world',
                'pi' = 3.14,
                'strvec' = letters[1:5],
                'intvec' = 1:5,
                'df' = data.frame('df1' = letters[1:5], 'df2' = 1:5),
                'z' = 26)


fn <- "test.rds"
fnb4 <- "test.rdsb64"
decoded <- "decoded.rds"
saveRDS(foodata, file = fn, compress = F)

#write base64 encoded version
library(base64enc)
txt <- base64enc::base64encode(fn)

#decode base64 encoded version
rdsbin <- base64enc::base64decode(txt)

# how to convert rdsbin back to the foodata list without using the intermediate step of saving to a file as follows?
ff <- file(decoded, "wb")
writeBin(rdsbin, ff)
close(ff)

bardata <- readRDS(decoded)

print(identical(foodata, bardata))
# [1] TRUE

Есть ли способ избежать чтения / записи промежуточных файлов? Или совсем другой подход?

1 Ответ

1 голос
/ 05 ноября 2019

Вам не нужны промежуточные файлы, вы можете использовать rawConnection для выполнения этих типов операций в памяти

#encore to base64 text string
encode_stream <- rawConnection(raw(), "r+")
saveRDS(foodata, file = encode_stream)

seek(encode_stream, 0) #reset to beginning of file
txt <- base64enc::base64encode(encode_stream)
close(encode_stream)


# txt is now a string that contains the data
# encoded in base64


# decode string to R object
rdsbin <- base64enc::base64decode(txt)
decode_stream <- rawConnection(rdsbin, "r")

bardata <- readRDS(decode_stream)
close(decode_stream)

# verify result
print(identical(foodata, bardata))
# [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...