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 Android Studio中如何把H5逻辑放在Assets 文件夹中以实现将h5代码打包为apk
  • ¥15 使用小程序wx.createWebAudioContext()开发节拍器
  • ¥15 关于#爬虫#的问题:请问HMDB代谢物爬虫的那个工具可以提供一下吗
  • ¥15 vue3+electron打包获取本地视频属性,文件夹里面有ffprobe.exe 文件还会报错这是什么原因呢?
  • ¥20 用51单片机控制急停。
  • ¥15 孟德尔随机化结果不一致
  • ¥15 在使用pyecharts时出现问题
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0