我正在http
通过下载一个大文件wget
,1.2TB。下载大约需要一周时间,目前已出现两次损坏(md5 校验失败,需要几天时间才能完成)。
有没有一种好的方法可以通过 http 逐个验证文件curl
?或者将其分成单独的块,以便我可以识别特定的坏块并重新下载该部分?
该文件是一个tar
档案,因此我相信可以在解压过程中按顺序识别每个块的损坏。
答案1
在服务器端,您可以使用dd
和md5sum
来对文件的每个块进行校验:
#!/bin/bash
FILENAME="$1"
FILESIZE=`stat --printf="%s" $FILENAME`
CHUNKSIZE=536870912 # 512MB
CHUNKNUM=0
while ! grep -q 'cannot skip' hash.log 2> /dev/null ; do
dd if=$FILENAME bs=$CHUNKSIZE skip=$CHUNKNUM count=1 2> hash.log | md5sum >> $FILENAME.md5
CHUNKNUM=$(( CHUNKNUM + 1 ))
done
rm hash.log
您将剩下一个$FILENAME.md5
包含所有块哈希值的单个文件。
您现在可以下载该大文件及其校验和,在文件上运行此脚本并比较哈希值。如果任何部分获得不匹配的哈希值,您可以使用 curl 仅下载文件的一部分(如果服务器支持 RANGE)并使用 dd 修补文件。
例如,如果块 2 的哈希值不匹配:
curl -s -r 536870912-1073741824 | dd of=somelargetarfile.tar seek=536870912 conv=notrunc
这将下载块 2,并用它修补较大的 tar 文件。
答案2
ThoriumBR 的回答很好,但我想补充一些额外的建议,以防您无法访问远程服务器。
您本地已经有一个(或多个)错误的下载。
使用 ThoriumBR 提供的拆分技巧,您可以在本地拆分这些文件并利用好的部分。
使用 curl(按照 ThoriumBR 的最后说明)将这些块中的每一个与下载的相同块进行比较。如果您有 2 个相同的块(二进制差异,不需要慢速 md5),您可以相对确定这是一个好的块。因此,将其保存在其他地方并重复下一个块。
所以:对于每个块:比较您的本地副本(如果有多个)并添加新下载的副本并进行比较,直到找到 2 个相同的块:这就是要保留的块。
这需要相当多的手动工作,但还是可行的。您甚至可以编写整个过程的脚本,但这样做(以及调试脚本)可能不值得付出努力。
答案3
在源服务器上,创建一个 BitTorrent .torrent 并将现有位置添加为 Web 种子 URL。BitTorrent 将验证这些块。如果需要,任何设法下载副本的客户端都可以为其做种。
这确实需要一份完整的文件副本来创建 .torrent。与 ThoriumBR 的解决方案非常相似,只是使用不同的工具。
如果仍有失败的文件和/或校验和,请比较每个文件和校验和。每次的结果相同可能表明您的传输是正确的,但远程文件与其已知的校验和不一致。