将内存中对象的 md5 与它作为 .Rds 的 md5 进行比较

compare md5 of an object in memory to the md5 of it as an .Rds

我想要一种方法来将内存中对象的 md5sum 与同一对象的 .Rds 文件的 md5sum 进行比较,并获得相同的哈希值。

我天真的尝试,没有产生相同的哈希值:

library(tools)
library(digest)

digest(c(1,2,3), algo = "md5")
#> [1] "af9e5c24af013c970922362b8850b060"

saveRDS(c(1,2,3), "123.Rds")

digest("123.Rds", algo = "md5", file = TRUE)
#> [1] "efb450974fefa662a54d1a2563a4f03b"
md5sum("123.Rds") # redundant
#>                            123.Rds 
#> "efb450974fefa662a54d1a2563a4f03b"

我知道 ,所以如果 saveRDS() 也在这样做,我怀疑它是,那么也许我正在寻找的是一个不这样做的 saveRDS() ?我可能在多个 R 版本的项目上工作,我想要一个解决方案,它会在 R 的(非古代)版本中提供相同的结果。

因此,rds 文件的摘要永远不会与实际数据的摘要完全匹配。 rds 文件通常会压缩数据并将添加元数据信息,如文件格式版本,因此字节不同,因此摘要也不同。

相反,考虑在写入 rds 的同时将数据摘要写入单独的文件。然后,如果以后要比较数据,只需读取缓存的摘要即可,而不必重新加载原始数据。例如

save_rds <- function(x, rdsname = paste0(substitute(x), ".rds"), digestname = paste0(rdsname,".digest")) {
  hash <- digest::digest(x, algo = "md5")
  saveRDS(x, rdsname)
  writeLines(hash, digestname)
}

你可以像这样使用所有这些功能

save_rds(iris)

它会写出iris.rdsiris.rds.digest

然后,如果你想稍后将数据与散列进行比较,你可以使用像

这样的辅助函数
digest_match <- function(x, digestfile) {
  hash <- digest::digest(x, algo = "md5")
  orig_hash <- readLines(digestfile)
  return( hash==orig_hash )
}

并且可以使用

进行测试
digest_match(iris, "iris.rds.digest")
# [1] TRUE
iris[1,1] <- 10
digest_match(iris, "iris.rds.digest")
# [1] FALSE