2017-09-03 41 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()))