Go 有没有比ioutil.ReadFile更快的替代方法?
我正在尝试制作一个基于md5校验和检查文件副本的程序。 我不确定我是否遗漏了什么,但是这个读取XCode安装程序应用程序的函数(它有8GB)使用了16GB的RamGo 有没有比ioutil.ReadFile更快的替代方法?,go,Go,我正在尝试制作一个基于md5校验和检查文件副本的程序。 我不确定我是否遗漏了什么,但是这个读取XCode安装程序应用程序的函数(它有8GB)使用了16GB的Ram func search() { unique := make(map[string]string) files, err := ioutil.ReadDir(".") if err != nil { log.Println(err) } for _, file := range
func search() {
unique := make(map[string]string)
files, err := ioutil.ReadDir(".")
if err != nil {
log.Println(err)
}
for _, file := range files {
fileName := file.Name()
fmt.Println("CHECKING:", fileName)
fi, err := os.Stat(fileName)
if err != nil {
fmt.Println(err)
continue
}
if fi.Mode().IsRegular() {
data, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Println(err)
continue
}
sum := md5.Sum(data)
hexDigest := hex.EncodeToString(sum[:])
if _, ok := unique[hexDigest]; ok == false {
unique[hexDigest] = fileName
} else {
fmt.Println("DUPLICATE:", fileName)
}
}
}
}
根据我的调试,问题在于文件读取
有没有更好的办法?
谢谢听起来16GB内存是你的问题,而不是速度本身 不要使用ReadFile将整个文件读入变量;从Open提供给您的读卡器复制io.Copy到hash/md5提供的编写器(返回一个,其中嵌入了一个io.Writer)。它一次只复制一点点,而不是将所有文件拉入RAM
这是一个在围棋很多地方都很有用的技巧;像
text/template
、compress/gzip
、net/http
等软件包都是针对读者和作者的。使用它们,您通常不需要创建巨大的[]字节或字符串;您可以将I/O接口相互挂钩,让它们为您传递内容片段。在垃圾收集语言中,节省内存也可以节省CPU工作。听起来16GB RAM是你的问题,而不是速度本身
不要使用ReadFile将整个文件读入变量;从Open提供给您的读卡器复制io.Copy到hash/md5提供的编写器(返回一个,其中嵌入了一个io.Writer)。它一次只复制一点点,而不是将所有文件拉入RAM
这是一个在围棋很多地方都很有用的技巧;像text/template
、compress/gzip
、net/http
等软件包都是针对读者和作者的。使用它们,您通常不需要创建巨大的[]字节或字符串;您可以将I/O接口相互挂钩,让它们为您传递内容片段。在垃圾收集语言中,节省内存往往也能节省CPU工作。Golang文档中有一个例子,介绍了您的情况
package main
import (
"crypto/md5"
"fmt"
"io"
"log"
"os"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
log.Fatal(err)
}
fmt.Printf("%x", h.Sum(nil))
}
对于您的情况,只需确保关闭循环中的文件,而不是延迟它们。或者将逻辑放入函数中。在Golang文档中有一个函数,它涵盖了您的案例
package main
import (
"crypto/md5"
"fmt"
"io"
"log"
"os"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
log.Fatal(err)
}
fmt.Printf("%x", h.Sum(nil))
}
对于您的情况,只需确保关闭循环中的文件,而不是延迟它们。或者将逻辑放入函数。尝试md5.New
,与io.Copy
结合使用。看一看。尝试使用md5.New
,并结合io.Copy
。看一看。