File: putObjWithProcess.go

package info (click to toggle)
golang-github-aws-aws-sdk-go 1.16.18%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, buster-backports, experimental
  • size: 93,084 kB
  • sloc: ruby: 193; makefile: 174; xml: 11
file content (102 lines) | stat: -rw-r--r-- 2,132 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// +build example

package main

import (
	"log"
	"os"
	"sync/atomic"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
)

type CustomReader struct {
	fp   *os.File
	size int64
	read int64
}

func (r *CustomReader) Read(p []byte) (int, error) {
	return r.fp.Read(p)
}

func (r *CustomReader) ReadAt(p []byte, off int64) (int, error) {
	n, err := r.fp.ReadAt(p, off)
	if err != nil {
		return n, err
	}

	// Got the length have read( or means has uploaded), and you can construct your message
	atomic.AddInt64(&r.read, int64(n))

	// I have no idea why the read length need to be div 2,
	// maybe the request read once when Sign and actually send call ReadAt again
	// It works for me
	log.Printf("total read:%d    progress:%d%%\n", r.read/2, int(float32(r.read*100/2)/float32(r.size)))

	return n, err
}

func (r *CustomReader) Seek(offset int64, whence int) (int64, error) {
	return r.fp.Seek(offset, whence)
}

func main() {
	if len(os.Args) < 4 {
		log.Println("USAGE ERROR: AWS_REGION=us-east-1 go run putObjWithProcess.go <credential> <bucket> <key for object> <local file name>")
		return
	}

	credential := os.Args[1]
	bucket := os.Args[2]
	key := os.Args[3]
	fileName := os.Args[4]

	creds := credentials.NewSharedCredentials(credential, "default")
	if _, err := creds.Get(); err != nil {
		log.Println("ERROR:", err)
		return
	}

	sess := session.New(&aws.Config{
		Credentials: creds,
	})

	file, err := os.Open(fileName)
	if err != nil {
		log.Println("ERROR:", err)
		return
	}

	fileInfo, err := file.Stat()
	if err != nil {
		log.Println("ERROR:", err)
		return
	}

	reader := &CustomReader{
		fp:   file,
		size: fileInfo.Size(),
	}

	uploader := s3manager.NewUploader(sess, func(u *s3manager.Uploader) {
		u.PartSize = 5 * 1024 * 1024
		u.LeavePartsOnError = true
	})

	output, err := uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(key),
		Body:   reader,
	})

	if err != nil {
		log.Println("ERROR:", err)
		return
	}

	log.Println(output.Location)
}