我正在try 从内存中写入压缩文件并上传到S3.
我正在将一个由type Data struct
组成的大型数组序列化为bufio.Writer
,它以逐行的方式写入gzip.Writer
:
### DATA AND SERIALIZATION
type Data struct {
field_1 int
field_2 string
}
func (d *Data) Serialize() []byte {
return []byte( fmt.Sprintf(`%d;%s\n`, d.field_1, d.field_2) )
}
### CREATE FILE AS COMPRESSED BYTES
var datas []*Data // assume this is filled
buffer := &bytes.Buffer{}
compressor := gzip.NewWriter(buffer)
writer := bufio.NewWriter(compressor)
for _, data := range datas {
writer.Write(data.Serialize())
}
writer.Flush()
compressor.Close()
### UPLOAD COMPRESSED FILE TO S3
key := "file.gz"
payload := bytes.NewReader(buffer.Bytes())
upload := &s3.PutObjectInput{
Body: payload,
Bucket: aws.String(bucket),
Key: aws.String(key),
}
这很管用,看起来很快,也有点效率.
然而,生成的文件虽然在Linux下被认为是文本文件,但通过\n
添加了not honor the line breaks.不确定这是操作系统特定的问题,还是通过某种方式定义文件类型的问题(例如,使用以file.txt.gz
或file.csv.gz
结尾的文件格式,或者通过添加特定的头字节),或者是我最初创建这些文件的方式的问题.
将完全限定的内存中文件类型创建为[]byte
(或通常在io.ReadSeeker
接口内)以逐行方式上载到S3、preferably的正确方式是什么?
Update:个
我能够通过将字符串包装在对fmt.Sprintln
的调用中来解决这个问题:
func (d *Data) Serialize() []byte {
return []byte( fmt.Sprintln(fmt.Sprintf(`%d;%s`, d.field_1, d.field_2) )
}
当看fmt.Sprintln
的实现时,它附加了\n
符文--肯定有我没有意识到的细微差别.