Skip to content

Commit de78d31

Browse files
add: remotefs/download support file download
1 parent 443adb9 commit de78d31

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

remotefs/download.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package remotefs
2+
3+
import (
4+
"crypto/sha256"
5+
"encoding/hex"
6+
"fmt"
7+
"io"
8+
"os"
9+
)
10+
11+
// ErrChecksumMismatch is returned when the checksum of the uploaded file does not match the local checksum.
12+
//var ErrChecksumMismatch = errors.New("checksum mismatch")
13+
14+
// Download a file from the remote host.
15+
func Download(fs FS, src, dst string) error {
16+
remote, err := fs.Open(src)
17+
if err != nil {
18+
return fmt.Errorf("open remote file for download: %w", err)
19+
}
20+
defer remote.Close()
21+
22+
remoteStat, err := remote.Stat()
23+
if err != nil {
24+
return fmt.Errorf("stat remote file for download: %w", err)
25+
}
26+
27+
remoteSum := sha256.New()
28+
localSum := sha256.New()
29+
30+
local, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, remoteStat.Mode())
31+
if err != nil {
32+
return fmt.Errorf("open local file for download: %w", err)
33+
}
34+
defer local.Close()
35+
36+
remoteReader := io.TeeReader(remote, remoteSum)
37+
if _, err := io.Copy(io.MultiWriter(local, localSum), remoteReader); err != nil {
38+
_ = local.Close()
39+
return fmt.Errorf("copy file from remote host: %w", err)
40+
}
41+
if err := local.Close(); err != nil {
42+
return fmt.Errorf("close local file after download: %w", err)
43+
}
44+
45+
ls := hex.EncodeToString(localSum.Sum(nil))
46+
rs := hex.EncodeToString(remoteSum.Sum(nil))
47+
fmt.Printf("local %s remote %s", ls, rs)
48+
if ls != rs {
49+
return ErrChecksumMismatch
50+
}
51+
52+
return nil
53+
}

0 commit comments

Comments
 (0)