Go 有没有比ioutil.ReadFile更快的替代方法?

Go 有没有比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

我正在尝试制作一个基于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 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
。看一看。