将字符串的 MD5 总和与文件内容进行比较 关于动机的无聊细节

问题描述

我正在尝试将字符串(在内存中)与文件内容进行比较,以查看它们是否相同。关于动机的无聊细节在问题下方是否有人关心。

我的困惑是,当我对文件内容进行哈希处理时,得到的结果与对字符串进行哈希处理时的结果不同。

js

想要做的只是 library(readr) library(digest) # write the string to the file the_string <- "here is some stuff" the_file <- "fake.txt" readr::write_lines(the_string,the_file) # both of these functions (predictably) give the same hash tools::md5sum(the_file) # "44b0350ee9f822d10f2f9ca7dbe54398" digest(file = the_file) # "44b0350ee9f822d10f2f9ca7dbe54398" # Now read it back to a string and get something different back_to_a_string <- readr::read_file(the_file) # "here is some stuff\n" digest(back_to_a_string) # "03ed1c8a2b997277100399bef6f88939" # add a newline because that's what write_lines did orig_with_newline <- paste0(the_string,"\n") # "here is some stuff\n" digest(orig_with_newline) # "03ed1c8a2b997277100399bef6f88939" 看看它们是否相同(它们是)但是返回 digest(orig_with_newline) == digest(file = the_file) 因为,如图所示,散列是不一样。

显然,我可以使用 FALSE文件读回字符串或将字符串写入临时文件,但这两种方法看起来都有些愚蠢和笨拙。我想这两个实际上都是很好的解决方案,我真的只是想了解为什么会发生这种情况,以便我可以更好地了解散列的工作原理。

关于动机的无聊细节

情况是我有一个函数可以将字符串写入文件,但是如果文件已经存在,那么除非用户明确传递read_file,否则它将出错。但是,如果文件存在,我想检查即将写入文件的字符串是否实际上与文件中已有的相同。如果是这种情况,那么我将跳过错误(和写入)。可以在循环中调用代码,如果用户不断看到此错误,即他们即将使用已在其中的相同内容覆盖文件,这将是令人讨厌的。

解决方法

简短回答:我认为您需要设置 serialize=FALSE。假设文件不包含额外的换行符(见下文),

digest(the_string,serialize=FALSE) ==  digest(file=the_file) ## TRUE

serialize 对命令的 file= 版本没有影响)

处理换行符

如果你读?write_lines,它只会说

sep: 行分隔符 ... [关于不同操作系统的默认值的信息]

对我来说,这对于是否在最后一行之后添加分隔符似乎不明确。 (您不希望“逗号分隔列表”以逗号结束 ...)

另一方面,?base::writeLines 更明确一些,

sep:字符串。要写入连接的字符串 在每行文本之后

如果您深入研究 source code of readr,您会发现它使用了

      output << na << sep;

对于每一行代码,即它的行为方式与 writeLines 相同。

如果您真的只想将字符串写入文件而不添加任何废话,我建议cat()

identical(the_string,{ cat(the_string,file=the_file); readr::read_file(the_file) }) ## TRUE