drwiupraq047311240 2017-04-24 15:25
浏览 67
已采纳

Golang IO读取文件无效的内存地址

I'm having some troubles trying to read a GZIP file from AWS S3. I have only a simple code and I'm getting the error panic: runtime error: invalid memory address or nil pointer dereference. But it still hard to find the problem.

The error message is saying that is the gzip.NewReader.... Why golang is reporting it? How could i solve it?

goroutine 1 [running]:
github.com/hensg/pushego/aws.GetGZIPProductsDump(0x7ffead44098f, 0xc, 0x7ffead44099f, 0x2f, 0x0, 0xc420190580, 0x0, 0x0)
        /home/henrique/go/src/github.com/hensg/pushego/aws/s3.go:47 +0x2e7
main.main()
        /home/henrique/go/src/github.com/hensg/pushego/pushego.go:28 +0x249

Main code (pushego.go)

package main

import (
    "bufio"
    "flag"
    "log"
    "os"
    "time"

    "github.com/hensg/pushego/aws"
)

func init() {
    log.SetOutput(os.Stdout)
}

func main() {
    log.Println("Starting...")

    var bucket, key string
    var timeout time.Duration

    flag.StringVar(&bucket, "b", "", "Bucket name")
    flag.StringVar(&key, "k", "", "Object key name")
    flag.DurationVar(&timeout, "d", 0, "Download timeout")
    flag.Parse()

    gzipReader, err := aws.GetGZIPDump(bucket, key, timeout) // line 28
    if err != nil {
        log.Fatal("Failed to create GZIP reader")
    }
   defer gzipReader.Close()

    scanner := bufio.NewScanner(gzipReader)
    for scanner.Scan() {
        log.Printf("Read: %s
", scanner.Text())
    }

    log.Printf("Successfully download file from %s/%s
", bucket, key)
}

Aws code (aws/s3.go)

package aws

import (
    "compress/gzip"
    "context"
    "log"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/request"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func GetGZIPProductsDump(bucket, key string, timeout time.Duration) (*gzip.Reader, error) {
    sess := session.Must(session.NewSession())
    svc := s3.New(sess)

    // Create a context with a timeout that will abort the download if it takes
    // more than the passed in timeout.
    ctx := context.Background()
    var cancelFn func()
    if timeout > 0 {
        ctx, cancelFn = context.WithTimeout(ctx, timeout)
    }
    // Ensure the context is canceled to prevent leaking.
    // See context package for more information, https://golang.org/pkg/context/
    defer cancelFn()

    // Uploads the object to S3. The Context will interrupt the request if the
    // timeout expires.
    resp, err := svc.GetObjectWithContext(ctx, &s3.GetObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
    })
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode {
            // If the SDK can determine the request or retry delay was canceled
            // by a context the CanceledErrorCode error code will be returned.
            log.Fatal("Download canceled due to timeout, %v
", err)
        } else {
            log.Fatal("Failed to download object, %v
", err)
        }
    }

    return gzip.NewReader(resp.Body) // line 47
}
  • 写回答

1条回答 默认 最新

  • dongzhang1987 2017-04-27 08:25
    关注

    The problem is related with the defer cancelFn(), currently that func is not set if the timeout is 0, this provoke a panic with a null pointer, so, you should move the defer inside of the previous if statement because it's the only point when is required to be used. The code of aws/s3.go have to be as the following.

    ...
    // Create a context with a timeout that will abort the download if it takes
    // more than the passed in timeout.
    ctx := context.Background()
    var cancelFn func()
    if timeout > 0 {
        ctx, cancelFn = context.WithTimeout(ctx, timeout)
        // Ensure the context is canceled to prevent leaking.
        // See context package for more information, https://golang.org/pkg/context/
        defer cancelFn()
    }
    ...
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制