putObjWithProcess.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // +build example
  2. package main
  3. import (
  4. "log"
  5. "os"
  6. "sync/atomic"
  7. "github.com/aws/aws-sdk-go/aws"
  8. "github.com/aws/aws-sdk-go/aws/credentials"
  9. "github.com/aws/aws-sdk-go/aws/session"
  10. "github.com/aws/aws-sdk-go/service/s3/s3manager"
  11. )
  12. type CustomReader struct {
  13. fp *os.File
  14. size int64
  15. read int64
  16. }
  17. func (r *CustomReader) Read(p []byte) (int, error) {
  18. return r.fp.Read(p)
  19. }
  20. func (r *CustomReader) ReadAt(p []byte, off int64) (int, error) {
  21. n, err := r.fp.ReadAt(p, off)
  22. if err != nil {
  23. return n, err
  24. }
  25. // Got the length have read( or means has uploaded), and you can construct your message
  26. atomic.AddInt64(&r.read, int64(n))
  27. // I have no idea why the read length need to be div 2,
  28. // maybe the request read once when Sign and actually send call ReadAt again
  29. // It works for me
  30. log.Printf("total read:%d progress:%d%%\n", r.read/2, int(float32(r.read*100/2)/float32(r.size)))
  31. return n, err
  32. }
  33. func (r *CustomReader) Seek(offset int64, whence int) (int64, error) {
  34. return r.fp.Seek(offset, whence)
  35. }
  36. func main() {
  37. if len(os.Args) < 4 {
  38. log.Println("USAGE ERROR: AWS_REGION=us-east-1 go run putObjWithProcess.go <credential> <bucket> <key for object> <local file name>")
  39. return
  40. }
  41. credential := os.Args[1]
  42. bucket := os.Args[2]
  43. key := os.Args[3]
  44. fileName := os.Args[4]
  45. creds := credentials.NewSharedCredentials(credential, "default")
  46. if _, err := creds.Get(); err != nil {
  47. log.Println("ERROR:", err)
  48. return
  49. }
  50. sess := session.New(&aws.Config{
  51. Credentials: creds,
  52. })
  53. file, err := os.Open(fileName)
  54. if err != nil {
  55. log.Println("ERROR:", err)
  56. return
  57. }
  58. fileInfo, err := file.Stat()
  59. if err != nil {
  60. log.Println("ERROR:", err)
  61. return
  62. }
  63. reader := &CustomReader{
  64. fp: file,
  65. size: fileInfo.Size(),
  66. }
  67. uploader := s3manager.NewUploader(sess, func(u *s3manager.Uploader) {
  68. u.PartSize = 5 * 1024 * 1024
  69. u.LeavePartsOnError = true
  70. })
  71. output, err := uploader.Upload(&s3manager.UploadInput{
  72. Bucket: aws.String(bucket),
  73. Key: aws.String(key),
  74. Body: reader,
  75. })
  76. if err != nil {
  77. log.Println("ERROR:", err)
  78. return
  79. }
  80. log.Println(output.Location)
  81. }