rvi*_*nca 3 go file-comparison filecompare
使用Python我可以做下一个:
equals = filecmp.cmp(file_old, file_new)
Run Code Online (Sandbox Code Playgroud)
在go语言中是否有任何内置函数可以做到这一点?我用Google搜索但没有成功.
我可以在hash/crc32
包中使用一些哈希函数,但这比上面的Python代码更有用.
Pit*_*ith 11
要完成@captncraig答案,如果您想知道这两个文件是否相同,可以使用OS软件包中的SameFile(fi1,fi2 FileInfo)方法.
SameFile报告fi1和fi2是否描述相同的文件.例如,在Unix上,这意味着两个底层结构的设备和inode字段是相同的;
否则,如果要检查文件内容,这里有一个解决方案,它逐行检查两个文件,避免加载内存中的整个文件.
首先尝试:https://play.golang.org/p/NlQZRrW1dT
编辑:按字节块读取,如果文件大小不同,则快速失败.https://play.golang.org/p/YyYWuCRJXV
const chunkSize = 64000
func deepCompare(file1, file2 string) bool {
// Check file size ...
f1, err := os.Open(file1)
if err != nil {
log.Fatal(err)
}
defer f1.Close()
f2, err := os.Open(file2)
if err != nil {
log.Fatal(err)
}
defer f2.Close()
for {
b1 := make([]byte, chunkSize)
_, err1 := f1.Read(b1)
b2 := make([]byte, chunkSize)
_, err2 := f2.Read(b2)
if err1 != nil || err2 != nil {
if err1 == io.EOF && err2 == io.EOF {
return true
} else if err1 == io.EOF || err2 == io.EOF {
return false
} else {
log.Fatal(err1, err2)
}
}
if !bytes.Equal(b1, b2) {
return false
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定该功能是否符合你的想法.从文档中,
除非给出浅并且为false,否则具有相同os.stat()签名的文件将被视为相同.
您的通话仅比较签字的os.stat
,其中仅包括:
你可以从os.Stat
函数中学习Go中的所有这三件事.这实际上只表明它们与同一文件或该文件的副本完全相同,或者是符号链接.
如果你想深入一点,你可以打开这两个文件并进行比较(python版本一次读取8k).
您可以使用crc或md5来散列两个文件,但如果在长文件的开头存在差异,则需要提前停止.我建议每次从每个阅读器读取一些字节数并与之比较bytes.Compare
.
怎么样使用bytes.Equal
?
package main
import (
"fmt"
"io/ioutil"
"log"
"bytes"
)
func main() {
// per comment, better to not read an entire file into memory
// this is simply a trivial example.
f1, err1 := ioutil.ReadFile("lines1.txt")
if err1 != nil {
log.Fatal(err1)
}
f2, err2 := ioutil.ReadFile("lines2.txt")
if err2 != nil {
log.Fatal(err2)
}
fmt.Println(bytes.Equal(f1, f2)) // Per comment, this is significantly more performant.
}
Run Code Online (Sandbox Code Playgroud)