go - 使用很少的内存散列大文件
问题描述
我需要散列非常大的文件(>10TB 文件)。所以我决定每 MB 散列 128KB。我的想法是将文件分成 1MB 的块,并且只对每个块的前 128KB 进行哈希处理。
以下代码有效,但它使用了大量的内存,我不知道为什么......
func partialMD5Hash(filePath string) string {
var blockSize int64 = 1024 * 1024
var sampleSize int64 = 1024 * 128
file, err := os.Open(filePath)
if err != nil {
return "ERROR"
}
defer file.Close()
fileInfo, _ := file.Stat()
fileSize := fileInfo.Size()
hash := md5.New()
var i int64
for i = 0; i < fileSize / blockSize; i++ {
sample := make([]byte, sampleSize)
_, err = file.Read(sample)
if err != nil {
return "ERROR"
}
hash.Write(sample)
_, err := file.Seek(blockSize-sampleSize, 1)
if err != nil {
return "ERROR"
}
}
return hex.EncodeToString(hash.Sum(nil))
}
任何帮助将不胜感激!
解决方案
这种方法和程序存在几个问题。
如果要散列一个大文件,则必须散列所有文件。对文件的某些部分进行采样不会检测到对您未采样的部分的修改。
您正在为每次迭代分配一个新缓冲区。相反,在 for 循环之外分配一个缓冲区,然后重用它。
此外,您似乎忽略了实际读取的字节数。所以:
block := make([]byte, blockSize)
for {
n, err = file.Read(block)
if n>0 {
hash.Write(sample[:n])
}
if err==io.EOF {
break
}
if err != nil {
return "ERROR"
}
}
但是,以下内容会更简洁:
io.Copy(hash,file)
推荐阅读
- google-apps-script - 将 Google 脚本用于 getEditResponeURL 代码时,我可以用特定文本替换 URL 链接吗?
- javascript - 基于用户特定选项创建的输入未在 post 方法中提交
- c# - WPF - 在运行时修改配置设置
- google-chrome-devtools - Chrome DevTools(检查设备)以空白标签打开
- javascript - 等待/停止代码执行,直到从服务器获取数据
- python - 在 Python 中为 Postgresql 传递和返回连接和游标
- base64 - Fluentd (td-agent) fluent-plugin-filter-base64-decode v.0.2.0 - 解码不正确
- typescript - 在 Typescript 中从 GatsbyLinkProps 创建组件?
- python - 标准 Scaler 拟合和转换步骤
- python - 如果第一个元素相同,如何将列表的第三个元素相乘?