'Why io.TeeReader provide nil object value? [closed]
I'm trying to run next chunk of go code to make a unique file name based on its hash and upload file to aws s3 bucket:
func PutImageToStore(f *bytes.Buffer) error {
hasher := md5.New()
io.TeeReader(f, hasher)
m5 := hex.EncodeToString(hasher.Sum(nil))
uploader := manager.NewUploader(awsS3Client)
// put object to storage:
result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{
Bucket: &myS3bucket,
Key: &m5,
Body: f,
})
return err
}
where awsS3client and myS3bucket are defined globally and f is an upload object, i.e earlier:
file, _, _ := r.FormFile("myimage")
io.Copy(f, file)
As a result of
PutImageToStore(f)
I always get Key value (i.e. &m5) equal "d41d8cd98f00b204e9800998ecf8427e" which as I understand is a hash of nil.
The aws s3 upload is correct, the only issue is with the uploaded object name.
When I change the line
io.TeeReader(f, hasher)
to
io.Copy(hasher, f)
I get correct object name, but the object itself get corrupted and has 0 (zero) bytes.
So why I always get such a narrowed result for an object name? What is a difference among io.Copy() and io.TeeReader in this case?
I looked at this example (What is the difference between io.TeeRearder and io.Copy?), but still do not understand my case.
Solution 1:[1]
You need to capture the io.Reader returned by io.TeeReader:
r := io.TeeReader(f, hasher)
then when you read all of r's content, it will get written also to the hasher, so:
body, err := io.ReadAll(r)
and body will contain all the bytes of the file.
You can achieve the same without an io.TeeReader since you need the whole body anyway:
body, err := io.ReadAll(f) // check err
_, err = io.Copy(hasher, bytes Newsreader(body)) // check err
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
