2017-09-03 76 views
0

我使用aws-sdk從s3存儲區下載文件。 S3下載功能需要的東西,實現io.WriterAt然而bytes.Buffer沒有實現。現在我正在創建一個實現io.WriterAt的文件,但是我想要一些內存中的東西。執行io.WriterAt的緩衝區go

回答

1

我不知道有什麼辦法在標準庫中做到這一點,但你可以編寫自己的緩衝區。

這真的不會那麼難......

編輯:我不能停止思考過這個問題,我結束了acidentally整個事情,享受:)

package main 

import (
    "errors" 
    "fmt" 
) 

func main() { 
    buff := NewWriteBuffer(0, 10) 

    buff.WriteAt([]byte("abc"), 5) 
    fmt.Printf("%#v\n", buff) 
} 

// WriteBuffer is a simple type that implements io.WriterAt on an in-memory buffer. 
// The zero value of this type is an empty buffer ready to use. 
type WriteBuffer struct { 
    d []byte 
    m int 
} 

// NewWriteBuffer creates and returns a new WriteBuffer with the given initial size and 
// maximum. If maximum is <= 0 it is unlimited. 
func NewWriteBuffer(size, max int) *WriteBuffer { 
    if max < size && max >= 0 { 
     max = size 
    } 
    return &WriteBuffer{make([]byte, size), max} 
} 

// SetMax sets the maximum capacity of the WriteBuffer. If the provided maximum is lower 
// than the current capacity but greater than 0 it is set to the current capacity, if 
// less than or equal to zero it is unlimited.. 
func (wb *WriteBuffer) SetMax(max int) { 
    if max < len(wb.d) && max >= 0 { 
     max = len(wb.d) 
    } 
    wb.m = max 
} 

// Bytes returns the WriteBuffer's underlying data. This value will remain valid so long 
// as no other methods are called on the WriteBuffer. 
func (wb *WriteBuffer) Bytes() []byte { 
    return wb.d 
} 

// Shape returns the current WriteBuffer size and its maximum if one was provided. 
func (wb *WriteBuffer) Shape() (int, int) { 
    return len(wb.d), wb.m 
} 

func (wb *WriteBuffer) WriteAt(dat []byte, off int64) (int, error) { 
    // Range/sanity checks. 
    if int(off) < 0 { 
     return 0, errors.New("Offset out of range (too small).") 
    } 
    if int(off)+len(dat) >= wb.m && wb.m > 0 { 
     return 0, errors.New("Offset+data length out of range (too large).") 
    } 

    // Check fast path extension 
    if int(off) == len(wb.d) { 
     wb.d = append(wb.d, dat...) 
     return len(dat), nil 
    } 

    // Check slower path extension 
    if int(off)+len(dat) >= len(wb.d) { 
     nd := make([]byte, int(off)+len(dat)) 
     copy(nd, wb.d) 
     wb.d = nd 
    } 

    // Once no extension is needed just copy bytes into place. 
    copy(wb.d[int(off):], dat) 
    return len(dat), nil 
} 
0

對於涉及AWS SDK的案例,請使用aws.WriteAtBuffer將S3對象下載到內存中。

requestInput := s3.GetObjectInput{ 
    Bucket: aws.String(bucket), 
    Key: aws.String(key), 
} 

buf := aws.NewWriteAtBuffer([]byte{}) 
downloader.Download(buf, &requestInput) 

fmt.Printf("Downloaded %v bytes", len(buf.Bytes()))