mirror of
https://github.com/rclone/rclone.git
synced 2024-11-23 07:34:17 +08:00
local: calculate md5sum on Read or Update since we check it in Copy()
This commit is contained in:
parent
07f9a1a9f0
commit
8b75fb14c5
|
@ -3,7 +3,9 @@ package local
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -37,6 +39,7 @@ type FsObjectLocal struct {
|
||||||
remote string // The remote path
|
remote string // The remote path
|
||||||
path string // The local path
|
path string // The local path
|
||||||
info os.FileInfo // Interface for file info
|
info os.FileInfo // Interface for file info
|
||||||
|
md5sum string // the md5sum of the object or "" if not calculated
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
@ -268,21 +271,30 @@ func (o *FsObjectLocal) Remote() string {
|
||||||
|
|
||||||
// Md5sum calculates the Md5sum of a file returning a lowercase hex string
|
// Md5sum calculates the Md5sum of a file returning a lowercase hex string
|
||||||
func (o *FsObjectLocal) Md5sum() (string, error) {
|
func (o *FsObjectLocal) Md5sum() (string, error) {
|
||||||
|
if o.md5sum != "" {
|
||||||
|
return o.md5sum, nil
|
||||||
|
}
|
||||||
in, err := os.Open(o.path)
|
in, err := os.Open(o.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Stats.Error()
|
fs.Stats.Error()
|
||||||
fs.Log(o, "Failed to open: %s", err)
|
fs.Log(o, "Failed to open: %s", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer in.Close() // FIXME ignoring error
|
|
||||||
hash := md5.New()
|
hash := md5.New()
|
||||||
_, err = io.Copy(hash, in)
|
_, err = io.Copy(hash, in)
|
||||||
|
closeErr := in.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Stats.Error()
|
fs.Stats.Error()
|
||||||
fs.Log(o, "Failed to read: %s", err)
|
fs.Log(o, "Failed to read: %s", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%x", hash.Sum(nil)), nil
|
if closeErr != nil {
|
||||||
|
fs.Stats.Error()
|
||||||
|
fs.Log(o, "Failed to close: %s", closeErr)
|
||||||
|
return "", closeErr
|
||||||
|
}
|
||||||
|
o.md5sum = hex.EncodeToString(hash.Sum(nil))
|
||||||
|
return o.md5sum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the size of an object in bytes
|
// Size returns the size of an object in bytes
|
||||||
|
@ -316,9 +328,47 @@ func (o *FsObjectLocal) Storable() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// localOpenFile wraps an io.ReadCloser and updates the md5sum of the
|
||||||
|
// object that is read
|
||||||
|
type localOpenFile struct {
|
||||||
|
o *FsObjectLocal // object that is open
|
||||||
|
in io.ReadCloser // handle we are wrapping
|
||||||
|
hash hash.Hash // currently accumulating MD5
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read bytes from the object - see io.Reader
|
||||||
|
func (file *localOpenFile) Read(p []byte) (n int, err error) {
|
||||||
|
n, err = file.in.Read(p)
|
||||||
|
if n > 0 {
|
||||||
|
// Hash routines never return an error
|
||||||
|
_, _ = file.hash.Write(p[:n])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the object and update the md5sum
|
||||||
|
func (file *localOpenFile) Close() (err error) {
|
||||||
|
err = file.in.Close()
|
||||||
|
if err == nil {
|
||||||
|
file.o.md5sum = hex.EncodeToString(file.hash.Sum(nil))
|
||||||
|
} else {
|
||||||
|
file.o.md5sum = ""
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Open an object for read
|
// Open an object for read
|
||||||
func (o *FsObjectLocal) Open() (in io.ReadCloser, err error) {
|
func (o *FsObjectLocal) Open() (in io.ReadCloser, err error) {
|
||||||
in, err = os.Open(o.path)
|
in, err = os.Open(o.path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Update the md5sum as we go along
|
||||||
|
in = &localOpenFile{
|
||||||
|
o: o,
|
||||||
|
in: in,
|
||||||
|
hash: md5.New(),
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +385,10 @@ func (o *FsObjectLocal) Update(in io.Reader, modTime time.Time, size int64) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the md5sum of the object we are reading as we go along
|
||||||
|
hash := md5.New()
|
||||||
|
in = io.TeeReader(in, hash)
|
||||||
|
|
||||||
_, err = io.Copy(out, in)
|
_, err = io.Copy(out, in)
|
||||||
outErr := out.Close()
|
outErr := out.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -344,6 +398,9 @@ func (o *FsObjectLocal) Update(in io.Reader, modTime time.Time, size int64) erro
|
||||||
return outErr
|
return outErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All successful so update the md5sum
|
||||||
|
o.md5sum = hex.EncodeToString(hash.Sum(nil))
|
||||||
|
|
||||||
// Set the mtime
|
// Set the mtime
|
||||||
o.SetModTime(modTime)
|
o.SetModTime(modTime)
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user