1// +build example 2 3package main 4 5import ( 6 "fmt" 7 "log" 8 "os" 9 "sync" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/aws/session" 13 "github.com/aws/aws-sdk-go/service/s3/s3manager" 14) 15 16type CustomReader struct { 17 fp *os.File 18 size int64 19 read int64 20 signMap map[int64]struct{} 21 mux sync.Mutex 22} 23 24func (r *CustomReader) Read(p []byte) (int, error) { 25 return r.fp.Read(p) 26} 27 28func (r *CustomReader) ReadAt(p []byte, off int64) (int, error) { 29 n, err := r.fp.ReadAt(p, off) 30 if err != nil { 31 return n, err 32 } 33 34 r.mux.Lock() 35 // Ignore the first signature call 36 if _, ok := r.signMap[off]; ok { 37 // Got the length have read( or means has uploaded), and you can construct your message 38 r.read += int64(n) 39 fmt.Printf("\rtotal read:%d progress:%d%%", r.read, int(float32(r.read*100)/float32(r.size))) 40 } else { 41 r.signMap[off] = struct{}{} 42 } 43 r.mux.Unlock() 44 return n, err 45} 46 47func (r *CustomReader) Seek(offset int64, whence int) (int64, error) { 48 return r.fp.Seek(offset, whence) 49} 50 51func main() { 52 if len(os.Args) < 4 { 53 log.Println("USAGE ERROR: AWS_REGION=us-west-2 go run -tags example putObjWithProcess.go <bucket> <key for object> <local file name>") 54 return 55 } 56 57 bucket := os.Args[1] 58 key := os.Args[2] 59 filename := os.Args[3] 60 61 sess, err := session.NewSession() 62 if err != nil { 63 log.Fatalf("failed to load session, %v", err) 64 } 65 66 file, err := os.Open(filename) 67 if err != nil { 68 log.Fatalf("failed to open file %v, %v", filename, err) 69 } 70 71 fileInfo, err := file.Stat() 72 if err != nil { 73 log.Fatalf("failed to stat file %v, %v", filename, err) 74 return 75 } 76 77 reader := &CustomReader{ 78 fp: file, 79 size: fileInfo.Size(), 80 signMap: map[int64]struct{}{}, 81 } 82 83 uploader := s3manager.NewUploader(sess, func(u *s3manager.Uploader) { 84 u.PartSize = 5 * 1024 * 1024 85 u.LeavePartsOnError = true 86 }) 87 88 output, err := uploader.Upload(&s3manager.UploadInput{ 89 Bucket: aws.String(bucket), 90 Key: aws.String(key), 91 Body: reader, 92 }) 93 if err != nil { 94 log.Fatalf("failed to put file %v, %v", filename, err) 95 return 96 } 97 98 fmt.Println() 99 log.Println(output.Location) 100} 101