1
1
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 05:11:06 +02:00

show hash progress on large files

This commit is contained in:
Zack 2024-05-28 16:08:31 -07:00
parent f83616e9bd
commit f6bd13fa06
3 changed files with 55 additions and 16 deletions

View file

@ -506,7 +506,7 @@ func (c *Client) sendCollectFiles(filesInfo []FileInfo) (err error) {
c.Options.HashAlgorithm = "xxhash" c.Options.HashAlgorithm = "xxhash"
} }
c.FilesToTransfer[i].Hash, err = utils.HashFile(fullPath, c.Options.HashAlgorithm) c.FilesToTransfer[i].Hash, err = utils.HashFile(fullPath, c.Options.HashAlgorithm, fileInfo.Size > 1e7)
log.Debugf("hashed %s to %x using %s", fullPath, c.FilesToTransfer[i].Hash, c.Options.HashAlgorithm) log.Debugf("hashed %s to %x using %s", fullPath, c.FilesToTransfer[i].Hash, c.Options.HashAlgorithm)
totalFilesSize += fileInfo.Size totalFilesSize += fileInfo.Size
if err != nil { if err != nil {

View file

@ -26,6 +26,7 @@ import (
"github.com/cespare/xxhash" "github.com/cespare/xxhash"
"github.com/kalafut/imohash" "github.com/kalafut/imohash"
"github.com/schollz/mnemonicode" "github.com/schollz/mnemonicode"
"github.com/schollz/progressbar/v3"
) )
const NbPinNumbers = 4 const NbPinNumbers = 4
@ -77,7 +78,11 @@ func GetInput(prompt string) string {
// HashFile returns the hash of a file or, in case of a symlink, the // HashFile returns the hash of a file or, in case of a symlink, the
// SHA256 hash of its target. Takes an argument to specify the algorithm to use. // SHA256 hash of its target. Takes an argument to specify the algorithm to use.
func HashFile(fname string, algorithm string) (hash256 []byte, err error) { func HashFile(fname string, algorithm string, showProgress ...bool) (hash256 []byte, err error) {
doShowProgress := false
if len(showProgress) > 0 {
doShowProgress = showProgress[0]
}
var fstats os.FileInfo var fstats os.FileInfo
fstats, err = os.Lstat(fname) fstats, err = os.Lstat(fname)
if err != nil { if err != nil {
@ -95,16 +100,16 @@ func HashFile(fname string, algorithm string) (hash256 []byte, err error) {
case "imohash": case "imohash":
return IMOHashFile(fname) return IMOHashFile(fname)
case "md5": case "md5":
return MD5HashFile(fname) return MD5HashFile(fname, doShowProgress)
case "xxhash": case "xxhash":
return XXHashFile(fname) return XXHashFile(fname, doShowProgress)
} }
err = fmt.Errorf("unspecified algorithm") err = fmt.Errorf("unspecified algorithm")
return return
} }
// MD5HashFile returns MD5 hash // MD5HashFile returns MD5 hash
func MD5HashFile(fname string) (hash256 []byte, err error) { func MD5HashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
f, err := os.Open(fname) f, err := os.Open(fname)
if err != nil { if err != nil {
return return
@ -112,8 +117,25 @@ func MD5HashFile(fname string) (hash256 []byte, err error) {
defer f.Close() defer f.Close()
h := md5.New() h := md5.New()
if _, err = io.Copy(h, f); err != nil { if doShowProgress {
return stat, _ := f.Stat()
fnameShort := path.Base(fname)
if len(fnameShort) > 20 {
fnameShort = fnameShort[:20] + "..."
}
bar := progressbar.NewOptions64(stat.Size(),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
progressbar.OptionClearOnFinish(),
)
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
return
}
} else {
if _, err = io.Copy(h, f); err != nil {
return
}
} }
hash256 = h.Sum(nil) hash256 = h.Sum(nil)
@ -137,7 +159,7 @@ func IMOHashFileFull(fname string) (hash []byte, err error) {
} }
// XXHashFile returns the xxhash of a file // XXHashFile returns the xxhash of a file
func XXHashFile(fname string) (hash256 []byte, err error) { func XXHashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
f, err := os.Open(fname) f, err := os.Open(fname)
if err != nil { if err != nil {
return return
@ -145,8 +167,25 @@ func XXHashFile(fname string) (hash256 []byte, err error) {
defer f.Close() defer f.Close()
h := xxhash.New() h := xxhash.New()
if _, err = io.Copy(h, f); err != nil { if doShowProgress {
return stat, _ := f.Stat()
fnameShort := path.Base(fname)
if len(fnameShort) > 20 {
fnameShort = fnameShort[:20] + "..."
}
bar := progressbar.NewOptions64(stat.Size(),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
progressbar.OptionClearOnFinish(),
)
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
return
}
} else {
if _, err = io.Copy(h, f); err != nil {
return
}
} }
hash256 = h.Sum(nil) hash256 = h.Sum(nil)

View file

@ -24,7 +24,7 @@ func BenchmarkMD5(b *testing.B) {
bigFile() bigFile()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
MD5HashFile("bigfile.test") MD5HashFile("bigfile.test", false)
} }
} }
@ -32,7 +32,7 @@ func BenchmarkXXHash(b *testing.B) {
bigFile() bigFile()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
XXHashFile("bigfile.test") XXHashFile("bigfile.test", false)
} }
} }
@ -78,10 +78,10 @@ func TestExists(t *testing.T) {
func TestMD5HashFile(t *testing.T) { func TestMD5HashFile(t *testing.T) {
bigFile() bigFile()
defer os.Remove("bigfile.test") defer os.Remove("bigfile.test")
b, err := MD5HashFile("bigfile.test") b, err := MD5HashFile("bigfile.test", false)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "8304ff018e02baad0e3555bade29a405", fmt.Sprintf("%x", b)) assert.Equal(t, "8304ff018e02baad0e3555bade29a405", fmt.Sprintf("%x", b))
_, err = MD5HashFile("bigfile.test.nofile") _, err = MD5HashFile("bigfile.test.nofile", false)
assert.NotNil(t, err) assert.NotNil(t, err)
} }
@ -96,10 +96,10 @@ func TestIMOHashFile(t *testing.T) {
func TestXXHashFile(t *testing.T) { func TestXXHashFile(t *testing.T) {
bigFile() bigFile()
defer os.Remove("bigfile.test") defer os.Remove("bigfile.test")
b, err := XXHashFile("bigfile.test") b, err := XXHashFile("bigfile.test", false)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "4918740eb5ccb6f7", fmt.Sprintf("%x", b)) assert.Equal(t, "4918740eb5ccb6f7", fmt.Sprintf("%x", b))
_, err = XXHashFile("nofile") _, err = XXHashFile("nofile", false)
assert.NotNil(t, err) assert.NotNil(t, err)
} }