【问题标题】:Get consistent md5 checksum of gzipped file using data.table and R.utils使用 data.table 和 R.utils 获取 gzip 文件的一致 md5 校验和
【发布时间】:2021-09-01 15:47:21
【问题描述】:

我正在尝试使用R.utils::gzipdata.table::fwritecompress = "gzip" 参数复制压缩文件的校验和,但我不断得到不同的结果。这是一个例子

library(data.table); library(R.utils); library(digest)

dt <- data.frame(a = c(1, 2, 3))

fwrite(dt, "r-utils.csv")
gzip("r-utils.csv")
fwrite(dt, "datatable-v1.csv.gz", compress = "gzip")

digest(file = "r-utils.csv.gz")
#> [1] "8d4073f4966f94ac5689c6e85de2d92d"
digest(file = "datatable-v1.csv.gz")
#> [1] "5d58f9eeefb166c6d50ac00f3215e689"

最初我虽然 fwrite 将文件名和时间戳存储在输出文件中(按照通常的 gzip 行为,没有 --no-name 选项),但情况似乎并非如此,因为我得到了对fwrite的不同调用中的相同校验和

fwrite(dt, "datatable-v2.csv.gz", compress = "gzip")
digest(file = "datatable-v2.csv.gz")
#> [1] "5d58f9eeefb166c6d50ac00f3215e689"

关于可能导致差异的任何想法?

PS。顺便说一句,未压缩文件的校验和是相同的

$ md5sum datatable-v1.csv 
7e034138dc91aa575d929c1ed65aa67c  datatable-v1.csv
$ md5sum r-utils.csv 
7e034138dc91aa575d929c1ed65aa67c  r-utils.csv

【问题讨论】:

  • "fwrite 正在将文件名和时间戳存储在输出文件中(按照通常的gzip 行为......)" 似乎很离谱:fwrite 写道将 CSV 格式的数据放入文件中,并将其命名为您提供的文件名。保存的时间戳由操作系统完成,与fwrite甚至R无关。gzip甚至不存储原始时间戳,它基于原始的前提“知道”原始名称name 是当前 gzip 后的名称,去掉了结尾的 .gz。这些实用程序相对幼稚是有充分理由的:简单是一件好事。
  • 问题出在你身上,因为你认为你需要能够从两个不同的压缩器以相同的输入获得完全相同的文件。对此从来没有任何保证。不同的压缩代码,不同设置的相同压缩代码,或相同设置的相同压缩代码的新版本,都可以合法地为相同的输入产生不同的输出。如果你认为你需要相同的输出,你只会无缘无故地感到沮丧和失望。如果您需要确保完整性,请检查解压缩数据,而不是压缩数据。

标签: r data.table gzip


【解决方案1】:

如果你查看字节,你会发现它们是不同的

r-utils.csv.gz
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   
00000000: 1F 8B 08 00 00 00 00 00 00 06 4B E4 E5 32 E4 E5    ..........Kde2de
00000010: 32 E2 E5 32 E6 E5 02 00 21 EB 62 BF 0C 00 00 00    2be2fe..!kb?....

datatable-v2.csv.gz
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   
00000000: 1F 8B 08 00 00 00 00 00 00 0A 4B E4 E5 02 00 56    ..........Kde..V
00000010: EF 2F E3 03 00 00 00 1F 8B 08 00 00 00 00 00 00    o/c.............
00000020: 0A 33 E4 E5 32 E2 E5 32 E6 E5 02 00 49 C4 FF 4D    .3de2be2fe..ID.M
00000030: 09 00 00 00                                        ....

所以 data.table 更长。这似乎是因为默认压缩设置不同。具体来说,这两种方法似乎使用不同的“窗口大小”参数。 data.table code uses a windowBits value of 31 (15+16) 将包括“输出中的尾随校验和”,但 R.utils::gzip 函数使用基本 R gzfile() 函数 which uses a windowBits value of -15 (MAX_WBITS) 并且该负值意味着不应使用尾随校验和。所以我认为这是 data.table 输出中额外字节的原因。

因为您可以使用不同的压缩级别设置和校验和以及 gzip 标头,所以如果使用两个不同的压缩管道,则不一定会为压缩版本的数据文件获得相同的校验和。所以有可能里面的数据是一样的,但实际压缩的文件不一样。

由于这些设置是包的 C 代码的一部分,并且对于基本 R,这不是您可以在 R 代码中更改的内容。这两种不同的方法不可能返回相同的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多