我有以下代码:
1,hyena
2,lion,https://en.wikipedia.org/wiki/File:Lion_waiting_in_Namibia.jpg
3,zebra
我正在尝试从S3解析CSV文件,对每一行进行一些操作,但是我得到了
package main
import (
"encoding/csv"
"fmt"
"io/ioutil"
"path"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"
)
var (
// TOKEN = os.Getenv("TOKEN")
svc s3iface.S3API
)
func main() {
// Panics if there is an error in creating session
svc = s3iface.S3API(s3.New(session.Must(session.NewSession())))
lambda.Start(Handler)
}
func Handler(evt events.S3Event) error {
for _, rec := range evt.Records {
key := rec.S3.Object.Key
dir, file := path.Split(key)
// Download the file from S3
obj, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(rec.S3.Bucket.Name),
Key: aws.String(key),
})
if err != nil {
return fmt.Errorf("error in downloading %s from S3: %s\n", key, err)
}
body, err := ioutil.ReadAll(obj.Body)
if err != nil {
return fmt.Errorf("error in reading file %s: %s\n", key, err)
}
reader := csv.NewReader(body)
record, err := reader.ReadAll()
if err != nil {
fmt.Println("Error", err)
}
for value := range record { // for i:=0; i<len(record)
fmt.Println("", record[value])
}
}
return nil
}
任何建议都值得赞赏
答案 0 :(得分:4)
错误提示:
不能在参数io.Reader中使用主体(类型[] byte) csv.NewReader: [] byte未实现io.Reader(缺少Read方法)
因为您正在将响应返回的[]byte
传递到csv.NewReader
需要通过正文来实现io.Reader
,以将其作为参数传递给csv.NewReader
。由于它以io.Reader
作为参数。尝试将代码更改为:
reader := csv.NewReader(bytes.NewBuffer(body))
record, err := reader.ReadAll()
if err != nil {
fmt.Println("Error", err)
}
还因为aws.GetObject返回指向GetObjectOutput
结构的指针。
func (c *S3) GetObject(input *GetObjectInput) (*GetObjectOutput, error)
本身实现了Reader
type GetObjectOutput struct {
....
// Object data.
Body io.ReadCloser `type:"blob"`
....
}
因此您可以将返回的正文直接传递给csv.NewReader。
另一件事是您可以使用Download Manager
s3manager软件包的Downloader提供了同时下载功能 来自S3的对象。下载器将使用以下命令写入S3对象内容 io.WriterAt。创建Downloader实例后,您可以调用 安全地从多个goroutine同时下载。
func (d Downloader) Download(w io.WriterAt, input *s3.GetObjectInput, options ...func(*Downloader)) (n int64, err error)
Download在S3中下载一个对象,并使用并发GET请求将有效负载写入w。
跨goroutine并发调用此方法是安全的。
// The session the S3 Downloader will use
sess := session.Must(session.NewSession())
// Create a downloader with the session and default options
downloader := s3manager.NewDownloader(sess)
// Create a file to write the S3 Object contents to.
f, err := os.Create(filename)
if err != nil {
return fmt.Errorf("failed to create file %q, %v", filename, err)
}
// Write the contents of S3 Object to the file
n, err := downloader.Download(f, &s3.GetObjectInput{
Bucket: aws.String(myBucket),
Key: aws.String(myString),
})
if err != nil {
return fmt.Errorf("failed to download file, %v", err)
}